Guru: A Simple Script That Capitalizes on IBM i’s Open Source Capabilities

Edit: Still one of my favorite trails, I returned in December and made it to Plateau Point.

Originally published by IT Jungle April 26, 2021

In my last piece, we got Yum and Bash running on IBM i. Now let’s build on that foundation to find an open campsite.

I’m serious. Recently I used an IBM i LPAR to schedule a hiking and camping trip to the Grand Canyon. Where to begin? My bio, perhaps. Here it’s mentioned that “Rob enjoys camping, hiking, biking, and backpacking through the mountains of Arizona. . . . His favorite trip was hiking to the blue waters of Havasupai, and he is planning on hiking the Grand Canyon in the near future.”

So last summer I went camping and ended up riding my bike around the South Rim. I told a friend about my plans to do more exploring there this year, including a rim to rim hike. Basically, he called me out. He wanted to do the hike, but he was also sick of hearing me go on about it.

Attempting a rim to rim hike in a single day isn’t recommended. It’s best to spend a night or two resting at the bottom at Phantom Ranch, one of the developed campsites, or to find your own spot in the back country (assuming you can obtain the proper permits and reservations). Of course the appeal of day hikes is that no permits are needed. However, you must be properly conditioned for this challenge:

“Over 250 people are rescued from the canyon each year. The difference between a great adventure in Grand Canyon and a trip to the hospital (or worse) is up to YOU. DO NOT attempt to hike from the rim to the river and back in one day, especially during the months of May to September.”

Though it was early April and not that hot yet, I took this advice. Rather than go rim to rim, I thought we’d try something of a practice hike down to Indian Garden. That covers around 10 miles round trip with the accompanying elevation changes. At that point we could gauge our comfort level, and if we felt good we could continue the hike to Plateau Point, which would add about three miles before we’d turn around. For some context, depending on the route chosen, if you do a rim to rim hike starting at the North Rim you’ll descend 6,000 feet, and then come up 4,500 feet to the top of the South Rim while covering around 24 miles.

Although plenty of free camping is available on National Forest land just south of the park entrance, I wanted to sleep closer to the trailhead, so I tried to get a spot at the developed Mather Campground near the South Rim of the Grand Canyon. The recreation.gov website had no availability at Mather for the nights I wanted, even though I’d periodically check and refresh. Eventually I got to wondering about other options, and sure enough, a site called campsitephotos.com has a campsite assist offering. This seemed to be what I was looking for.

I clicked on the arrow and entered my destination:

There were options to narrow the search, but I wasn’t picky.

I chose a Matrix scan:

Then I entered some potential dates:

I provided my cell number to receive text alerts:

Then it hit me up with the pricing options:

That was affordable enough, but what if I wanted to make changes? What if I wanted to check more often than every 15 minutes? How hard was it to roll my own website scraper? I searched further and found some interesting code on GitHub. (More readable versions are typed below each of the following screen shots, which came from: https://github.com/banool/recreation-gov-campsite-checker)

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)

Installation

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

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

For all I know this code may be in use or even modified by Campsite Assist. In any event it seemed like a great tool to run on an IBM i LPAR. And sure, many people may see Linux as a more natural environment for something like this, but there’s value in getting these tools to run on IBM i, particularly when it’s this simple.

I logged in via putty and checked to see if Python3 was installed:

	bash-4.4$ python3
	bash: python3: command not found

I used the find command to check for yum:

	bash-4.4$ find / -name yum -print
	/QOpenSys/pkgs/bin/yum

Then I used Yum to install Python3. I omitted many of the messages and skipped to the end:

	bash-4.4$ /QOpenSys/pkgs/bin/yum install python3
	Installed:
	  python3.ppc64 0:3.6.12-1
	Dependency Installed:
	  libreadline8.ppc64 0:8.0-1

Complete!

I also wanted to install git so I could copy the code from GitHub.

	bash-4.4$ /QOpenSys/pkgs/bin/yum install git
	Installed:
	  git.ppc64 0:2.26.2-3
	Dependency Installed:
	  libpcre2-8-0.ppc64 0:10.35-1

I wasn’t sure where git was installed, so I ran find and then used git to clone the website:

	bash-4.4$ find / -name git -print
	/QopenSys/pkgs/bin/git
	bash-4.4$ /QOpenSys/pkgs/bin/git clone https://github.com/banool/recreation-gov-campsite-checker.git 
	Cloning into 'recreation-gov-campsite-checker'...
	remote: Enumerating objects: 16, done.
	remote: Counting objects: 100% (16/16), done.
	remote: Compressing objects: 100% (12/12), done.
	remote: Total 161 (delta 7), reused 11 (delta 4), pack-reused 145
	Receiving objects: 100% (161/161), 42.65 KiB | 2.24 MiB/s, done.
	Resolving deltas: 100% (77/77), done.
	bash-4.4$ ls -ld rec*
	drwxr-sr-x    4 rob 0             12288 Apr  3 07:20 recreation-gov-campsite-checker
	bash-4.4$ cd recreation-gov-campsite-checker/
	bash-4.4$ ls
	README.md                      camping.py                     fake_twitter_credentials.json  notifier.py                    	other                          requirements.txt               setup.py

Now it was just a matter of running through the installation instructions listed at the beginning of this section:

	bash-4.4$ /QOpenSys/pkgs/bin/python3 -m venv myvenv
	bash-4.4$ source myvenv/bin/activate
	(myvenv) bash-4.4$
	(myvenv) bash-4.4$ pip install --upgrade pip
	Collecting pip
	  Downloading 	https://files.pythonhosted.org/packages/fe/ef/60d7ba03b5c442309ef42e7d69959f73aacccd0d86008362a681c4698e83/pip-21.0.1-py3-none-any.whl (1.5MB)
	    100% |################################| 1.5MB 3.1MB/s
	Installing collected packages: pip
	  Found existing installation: pip 18.1
	    Uninstalling pip-18.1:
	      Successfully uninstalled pip-18.1
Successfully installed pip-21.0.1
	(myvenv) bash-4.4$ pip install -r requirements.txt

There was quite a bit of output once I’d finished:

Successfully installed Click-7.0 appdirs-1.4.3 attrs-18.2.0 black-18.9b0 certifi-2018.11.29 chardet-3.0.4 fake-useragent-0.1.11 future-0.17.1 idna-2.8 isort-4.3.4 oauthlib-3.0.1 python-dateutil-2.8.1 python-twitter-3.5 requests-2.21.0 requests-oauthlib-1.2.0 six-1.15.0 soupsieve-1.8 toml-0.10.0 urllib3-1.24.2

I got some errors when I ran the code, which uses emojis to alert you on the status of the search. Rather than try and make that work, I changed the emojis to English text by running:

	vi camping.py 

Then I edited 29 and 30:

	  +29 SUCCESS_EMOJI = "yay"
	   +30  FAILURE_EMOJI = "boo"

At this point it ran as expected. I tried a few different date ranges to see what was being returned:

(myvenv) bash-4.4$ python3 camping.py --start-date 2021-04-06 --end-date 2021-04-08 --nights 2 --parks 232490
There are no campsites available :(
boo MATHER CAMPGROUND (232490): 0 site(s) available out of 357 site(s)
(myvenv) bash-4.4$ python3 camping.py --start-date 2021-04-06 --end-date 2021-05-08 --nights 2 --parks 232490
There are campsites available from 2021-04-06 to 2021-05-08!!!
yay MATHER CAMPGROUND (232490): 23 site(s) available out of 357 site(s)

To view the raw data being returned, turn on debug mode with — debug. You’ll then get specific campsite IDs and available dates:

(myvenv) bash-4.4$ python3 camping.py --start-date 2021-04-01 --end-date 2021-04-09 --parks 232490 
--debug   2> test.out
	(myvenv) bash-4.4$ cat test.out 
	2021-04-03 15:38:36,066 - 19668 - DEBUG - Querying for 232490 with these params:
	 {'start_date': '2021-04-01T00:00:00.000Z'}
	2021-04-03 15:38:39,031 - 19668 - DEBUG - Information for park 232490: {
	  "4079": [],
	  "4080": [],
	  "4081": [],
	  "4082": [],
	  "4083": [],
	  "4084": [],
	  "4085": [
	    "2021-04-28T00:00:00Z"
	  ],
	  "4086": [],
	  "4087": [],
	  "4088": [],
	  "4089": [],
	  "4090": [
	    "2021-04-27T00:00:00Z"
	  ],
	  "4091": [],
	  "4092": [
	    "2021-04-28T00:00:00Z"

That’s just a taste. The actual file has tons of additional information. At this point, I created a quick and dirty script called test.bash:

	python3 camping.py --start-date 2021-04-01 --end-date 2021-04-09 --parks 232490 
	--debug   2> test.out
	cat test.out | grep '2021-04-0[5678]T'

The first line ran the code and sent the debug output to a file; the second line read through the file and searched for a date string. I broadened my search to April 5-8 rather than April 6-7 so I could see results even when my target dates were unavailable. Wild cards and regular expressions are beyond the scope of this article, and I realize there are probably more elegant ways to accomplish this, but I’d be happy to hear how you would have done it.

I made the script executable by running:

	(myenv) bash-4.4$ chmod u+x test.bash

Then I ran it with:

	(myvenv) bash-4.4$ ./test.bash
	There are no campsites available :(
	boo MATHER CAMPGROUND (232490): 0 site(s) available out of 357 site(s)
	    "2021-04-05T00:00:00Z",
	    "2021-04-07T00:00:00Z",
	    "2021-04-07T00:00:00Z"
	    "2021-04-08T00:00:00Z"

At this point I created a simple loop that would run on the command line.

	(myvenv) bash-4.4$ while true
	> do date
	> ./test.bash
	> sleep 300
	> done
	Sat Apr  3 08:34:35 CST 2021
	There are no campsites available :(
	boo MATHER CAMPGROUND (232490): 0 site(s) available out of 357 site(s)
	    "2021-04-05T00:00:00Z",
	    "2021-04-07T00:00:00Z",
	    "2021-04-07T00:00:00Z"
	    "2021-04-08T00:00:00Z"

Rather than hammer the site, I gave it a 5-minute delay (300 seconds). Yes, even 5 minutes may be excessive, but I figured it wouldn’t need to run for long. In any event, that interval worked for me. After about 25 minutes, an open campsite that fit my criteria became available.

During this test run you can see the changes in availability:

	Sat Apr  3 08:34:35 CST 2021
	There are no campsites available :(
	boo MATHER CAMPGROUND (232490): 0 site(s) available out of 357 site(s)
	    "2021-04-05T00:00:00Z",
	    "2021-04-07T00:00:00Z",
	    "2021-04-07T00:00:00Z"
	    "2021-04-08T00:00:00Z"
	Sat Apr  3 08:39:38 CST 2021
	There are no campsites available :(
	boo MATHER CAMPGROUND (232490): 0 site(s) available out of 357 site(s)
	    "2021-04-05T00:00:00Z",
	    "2021-04-07T00:00:00Z",
	    "2021-04-08T00:00:00Z"
	Sat Apr  3 08:44:39 CST 2021
	There are no campsites available :(
	boo MATHER CAMPGROUND (232490): 0 site(s) available out of 357 site(s)
	    "2021-04-07T00:00:00Z",
	    "2021-04-08T00:00:00Z"
	Sat Apr  3 08:49:42 CST 2021
	There are no campsites available :(
	boo MATHER CAMPGROUND (232490): 0 site(s) available out of 357 site(s)
	    "2021-04-08T00:00:00Z"
	Sat Apr  3 08:54:45 CST 2021
	There are no campsites available :(
	boo MATHER CAMPGROUND (232490): 0 site(s) available out of 357 site(s)
	    "2021-04-08T00:00:00Z"

To get this going, you need to know your campground ID. Search for your campground on recreation.gov; the ID is in your title bar.

This will work for any campsite. Emojis aside, this code worked without any modifications. Everything ran as described on GitHub, and it was running on a Power Systems server. Incidentally, I also tried it on a Linux machine to make sure there were no differences between the platforms. Indeed, everything was the same, right down to the emoji issue.

As it happened, my buddy couldn’t make that trip, so my son joined me for some camping. We hiked down to Indian Garden and back along the Bright Angel trail. We got a late start, so we made sure to pack it in before dark rather than continue on to Plateau Point. Physically I felt up to it, but I also realized I’ll need to train more for the real deal; coming back uphill is no joke. My legs were sore and stiff for days after.

Knowing that I had a reservation at a campsite that was relatively close to where we started/ended the hike made the experience even more enjoyable. Sure, this isn’t exactly a traditional use for IBM i, but my tale confirms what you should already know. Using modern tools and techniques, this OS is capable of solving all kinds of interesting problems.