β¨ GoingToCamp Provider π#99
Conversation
acaloiaro
left a comment
There was a problem hiding this comment.
A few items not yet noted by TODO in the code.
| search_window: Union[SearchWindow, List[SearchWindow]], | ||
| recreation_area: Optional[Union[List[int], int]] = None, | ||
| campsites: Optional[Union[List[int], int]] = None, | ||
| weekends_only: bool = False, |
There was a problem hiding this comment.
Support weekends only?
There was a problem hiding this comment.
The BaseCampingSearch base class should handle all of this heavy lifting.
Here's how it works inside with Recreation.Gov in the final get_all_campsites abstractmethod:
camply/camply/search/search_recreationdotgov.py
Lines 247 to 257 in d1fb5d5
The idea is that found_campsites array is a list of AvailableCampsite objects which may or may not fit the search criteria. Every AvailableCampsite has a booking nights length of 1 and the _filter_date_overlap will take care of filtering to match dates (including weekends) and _consolidate_campsites will handle combining consecutive nights together for the same campsite/campground ID when the user specifies that nights > 1.
Yellowstone was a bit different than this since it allowed you to forward the nights param directly to the API to only return bookings matching that.
6e9b07e to
dc38b65
Compare
|
The current state of this PR Is that, due to each rec area having its own naming conventions for equipment, equipment matching needs to be improved. |
dc38b65 to
75b1392
Compare
| "not case-sensitive.", | ||
| ) | ||
| equipment_id_argument = click.option( | ||
| "--equipment-id", |
There was a problem hiding this comment.
@juftin What are your thoughts on the added complexity of having both --equipment and --equipment-id?
--equipment-id is the easiest way forward to support Going To Camp's native equipment type support, in lieu of the (equipment, length) tuple that powers Rec.gov and Yellowstone. I'm not in love with having both, and equally not in love with overloading --equipment to support both rec.gov and goingtocamp.
There was a problem hiding this comment.
One middle ground alternative might be to break the --equipment API up into --equipment and --equipment-length (default 0, although I think -1 is more fitting sentinel value).
After breaking up the --equipment API it could be overloaded such that --equipment takes an equipment name, i.e. trailer, tent, etc -- or an equipment ID, for providers that support specific equipment out of the box.
There was a problem hiding this comment.
I'm open to breaking it up. My idea with --equipment accepting a tuple of equipment-name and equipment-length is that it would allow you to specify for multiple types of equipment, with different lengths:
camply campsites \
--rec-area 2991 \
--start-date 2022-07-09 \
--end-date 2022-07-17 \
--nights 5 \
--equipment RV 25 \
--trailer 15But now that I'm thinking about it - maybe that's not a common scenario and specifying a single equipment name (or id) and a single equipment length is more useful.
There was a problem hiding this comment.
π I'll take a stab at implementing them as two params and a single equipment-per-search. Seems like a reasonable middle ground.
|
Hey @acaloiaro feedback is coming soon, I promise. I'm a little preoccupied with some work and personal things at the moment but I'll be following up here as soon as I can |
0b2a1b7 to
5730500
Compare
|
@juftin This PR is ready for a proper review. Notable changes since you may have last seen it
|
| @click.option( | ||
| "--debug/--no-debug", default=False, help="Enable extra debugging output." | ||
| ) | ||
| @click.option( |
There was a problem hiding this comment.
π π @acaloiaro thank you so much - I'm starting to look at this on my end. I've got some big life events this week (π€΅ π π°ββοΈ ) and so review will be delayed.
One question on the --provider change:
- I love moving
--providerto the top level of the CLI. One question though, does this mean that passing it in after--campsiteswill break? I really like options like--profilein the AWS CLI where you can just throw it in wherever. I'm wondering if Click gives us any kind of flexibility on those universal options like--provider
There was a problem hiding this comment.
In its current implementation, I think it does break that behavior, but let me see if click will allow the alternate behavior at the same time.
There was a problem hiding this comment.
BTW I still need to add some tests and manually test more things, like notifications and configuration file support, before this PR will actually be ready for consideration. I just wanted to get another set of eyes on it for now.
There was a problem hiding this comment.
Hey @acaloiaro following up here. I've actually moved --provider and --debug to the top level and lower level CLI namespaces via some Click Contexts on Release 0.7.0.
I've also added a Discord Server - it's pretty much empty but I wanted to make sure there's an easy place to collaborate for features like yours. Is there anything I can do to help you along on this right now?
There was a problem hiding this comment.
Cool! I'm taking a look at this PR again now and will try to get it polished up.
5730500 to
5baa965
Compare
4e79ec3 to
1bbb8a6
Compare
1bbb8a6 to
11111c4
Compare
0108ad7 to
711c098
Compare
| @validator("start_date") | ||
| def start_date_must_be_in_future(self, v): | ||
| """ | ||
| Validate that start_date is in the future | ||
| """ | ||
| current_date = datetime.datetime.now().date() | ||
| print(v, current_date) | ||
| if v < current_date: | ||
| raise ValueError("must be in the future") | ||
|
|
||
| return v |
There was a problem hiding this comment.
Validators use cls instead of self - kind of confusing but that's what's throwing the error here: https://github.com/juftin/camply/actions/runs/3576943050/jobs/6015349570#step:8:427
I like the idea of validating the start date at the SearchWindow level - currently I coerce the SearchWindow into being compliant with the current date here:
camply/camply/search/base_search.py
Lines 542 to 569 in 173ee47
If we need to set this data validation at the SearchWindow level these validators should coerce the dates into >= current date instead of raising an Error.
I kind of like the idea of being able to provide a start date in the past as long as the end date is in the future without raising an error. What do you think?
There was a problem hiding this comment.
Yeah that makes sense; I'd prefer it to be more tolerant of bad input.
| timestamp_range = [] | ||
| if type(date) is Timestamp: | ||
| timestamp_range = date_range(start=date.to_pydatetime(), periods=periods) | ||
| else: | ||
| timestamp_range = date_range(start=date, periods=periods) |
There was a problem hiding this comment.
Nice - I wish I could easily remember exactly where my datetime objects get converted into Timestamps and then become difficult to deal with.
There was a problem hiding this comment.
I originally I remember intending to track that down and factoring this code out. I vaguely recall this having something to do with dates coming from a config file? Does that ring any bells?
There was a problem hiding this comment.
I think there are a couple places where I convert an array of AvailableCampsite objects into a pandas DataFrame, do some manipulation, and then transform them back into an array of AvailableCampsite - somehow tunring them into Timestamp along the way. This might be the big offender here:
camply/camply/search/base_search.py
Lines 752 to 769 in 173ee47
| @camply_command_line.command() | ||
| @rec_area_argument | ||
| @provider_argument | ||
| @click.pass_obj | ||
| def equipment_types( | ||
| context: CamplyContext, | ||
| rec_area: Optional[int] = None, | ||
| provider: str = DEFAULT_CAMPLY_PROVIDER, | ||
| ) -> None: | ||
| """ | ||
| Retrieve a list of equipment supported by the current provider/recreaton area | ||
|
|
||
| Equipment are camping equipment that can be used at a campsite. Different providers | ||
| and recreation areas have different types of equipment for which reservations can be made. | ||
| """ |
There was a problem hiding this comment.
This is all looking very clean - it's a great implementation. I've got a couple questions on here but I'm close to getting this ready for merge.
There's currently a GitHub Actions Secrets error that occurs when I merge directly to main from an outside repo - let's target a different branch on juftin/camply and then I'll go to main from there.
I'd like to get some usage of GoingToCamp documented - including how to use the new equipment-types command. I've got a placeholder here: #156. If it's helpful we can merge this PR into that branch or merge both PRs into a new branch.
| sites = self.campsite_finder.list_site_availability( | ||
| campground, | ||
| self.search_window[0].start_date, | ||
| self.search_window[0].end_date, |
There was a problem hiding this comment.
This smells. It looks like we should be iterating over all search windows. I wasn't aware that multiple search windows were a valid use case.
There was a problem hiding this comment.
There are also a few of properties set on the BaseCampingSearch instance that might be useful:
camply/camply/search/base_search.py
Lines 90 to 92 in 173ee47
self.search_dates= An array of all Possible Dates from Among Your Search Window that are today or in the futureself.search_months= An array of all of the months that comprise the search window expressed as a first of the month dt objectself.search_nights= The number of nights to search - this is also validated so if you tell camply that you want to search for weekends only but you want to stay for 6 nights, it's adjusted to 5 - or if your search window is 3 days wide but you ask for 4 nights
| @camply_command_line.command() | ||
| @rec_area_argument | ||
| @provider_argument | ||
| @click.pass_obj | ||
| def equipment_types( | ||
| context: CamplyContext, | ||
| rec_area: Optional[int] = None, | ||
| provider: str = DEFAULT_CAMPLY_PROVIDER, | ||
| ) -> None: | ||
| """ | ||
| Retrieve a list of equipment supported by the current provider/recreaton area | ||
|
|
||
| Equipment are camping equipment that can be used at a campsite. Different providers | ||
| and recreation areas have different types of equipment for which reservations can be made. | ||
| """ |
| # Rec area: Long Point Region | ||
| # Campground: Waterford North Conservation Area | ||
| # Equipment: 1 tent | ||
| camply \ | ||
| --debug \ | ||
| --provider goingtocamp \ | ||
| campsites \ | ||
| --rec-area 1 \ | ||
| --start-date 2023-09-01 \ | ||
| --end-date 2023-09-02 \ | ||
| --equipment-id -32768 \ | ||
| --campground -2147483643 \ |
There was a problem hiding this comment.
Nice, these are great. Thank you so much for the testing contributions.
juftin
left a comment
There was a problem hiding this comment.
I feel great with all of this - I'll leave it up to you for when you're fully happy with merging.
I'm guessing that currently I only have the permissions to hit those buttons. How should that merge go, any preferences? For me, ideally the final merge into main is single clean commit belonging to you.
f7f63b8 to
d1092e7
Compare
|
I'm going to move forward and get this code staged to go to main. It's going to an intermediate release branch in the meantime where I can finally bring my testing changes up to date with it. π |
* Add going to camp support * Fix type hints for _fetch_nested_keys * Add missing 'provider' argument to 'campsites()' * Fix invalid equipment parameter name * Fix provider config for recreation-areas * flake8 can get some satisfaction * Add python tests for going to camp search * Fix recursive resource fetch bug * Revert back to requipment-id instead of changing the --equipment API * Check off the final TODO list * Update camply/search/search_going_to_camp.py * Update camply/search/search_going_to_camp.py * Refactor 'self->cls' in validator * Add multiple search window support to search library * Coerce start date to 'today' when it's in the past * Skip all sites with zero capacity
# [v0.8.0](v0.7.6...v0.8.0) (2022-12-27) ## β¨ New Features - [`6620f4c`](6620f4c) GoingToCamp Provider π (#99) (Issues: [`#99`](#99))
* Add support for tours (ticket and timed-entry) as new providers A tour facility is currently modeled as a campground and each individual tour is a campsite. User interface was not updated yet but the logic does the work as expected. * Add RecreationDotGovDailyTicket and RecreationDotGovDailyTimedEntry With this endpoint, available time slots can be extracted. They're attached as equipments on each tour (as campsite). * Flake8 + ABC * Add support for tours (ticket and timed-entry) as new providers A tour facility is currently modeled as a campground and each individual tour is a campsite. User interface was not updated yet but the logic does the work as expected. * Add RecreationDotGovDailyTicket and RecreationDotGovDailyTimedEntry With this endpoint, available time slots can be extracted. They're attached as equipments on each tour (as campsite). * RecreationDotGov Tours (#1) Flake8 + ABC * Fix Flake8 lint errors * π semantic-release * π 0.7.4 # [v0.7.4](v0.7.3...v0.7.4) (2022-12-22) ## π Bug Fixes - [`6d7c682`](6d7c682) semantic-release * π· publish pre-releases * π Docs + GA * π Docker Home Directory (#173) * π 0.7.5 # [v0.7.5](v0.7.4...v0.7.5) (2022-12-22) ## π Bug Fixes - [`6c92220`](6c92220) Docker Home Directory (#173) (Issues: [`#173`](#173)) * π CI/CD Triggers (#174) * π 0.7.6 # [v0.7.6](v0.7.5...v0.7.6) (2022-12-22) ## π Bug Fixes - [`92169f8`](92169f8) CI/CD Triggers (#174) (Issues: [`#174`](#174)) * β¨ GoingToCamp Provider π (#99) * Add going to camp support * Fix type hints for _fetch_nested_keys * Add missing 'provider' argument to 'campsites()' * Fix invalid equipment parameter name * Fix provider config for recreation-areas * flake8 can get some satisfaction * Add python tests for going to camp search * Fix recursive resource fetch bug * Revert back to requipment-id instead of changing the --equipment API * Check off the final TODO list * Update camply/search/search_going_to_camp.py * Update camply/search/search_going_to_camp.py * Refactor 'self->cls' in validator * Add multiple search window support to search library * Coerce start date to 'today' when it's in the past * Skip all sites with zero capacity * β Testing Improvements: Cassettes and CLIRunner (#155) * Add going to camp support * Fix type hints for _fetch_nested_keys * Add missing 'provider' argument to 'campsites()' * Fix invalid equipment parameter name * Fix provider config for recreation-areas * flake8 can get some satisfaction * Add python tests for going to camp search * Fix recursive resource fetch bug * Revert back to requipment-id instead of changing the --equipment API * Testing Improvements: Cassettes and CLIRunner * Testing Improvements: Cassettes and CLIRunner * Testing Improvements: Cassettes and CLIRunner * Testing Improvements: Cassettes and CLIRunner * Testing Improvements: Cassettes and CLIRunner * Check off the final TODO list * Testing Improvements: Cassettes and CLIRunner * Testing Improvements: Cassettes and CLIRunner * Update camply/search/search_going_to_camp.py * Update camply/search/search_going_to_camp.py * Refactor 'self->cls' in validator * Add multiple search window support to search library * Coerce start date to 'today' when it's in the past * GoingToCamp + Tests * π§ Merging Latest Co-authored-by: Adriano Caloiaro <code@adriano.fyi> Co-authored-by: Adriano <3331648+acaloiaro@users.noreply.github.com> * π dependency updates (#172) * π dependency updates * π dependency updates * π dependency updates * π Providers Documentation (#156) * feature/goingtocamp * Add a blurb about GoingToCamp provider (#175) * GoingToCamp Documentation * GoingToCamp Documentation * GoingToCamp Documentation Co-authored-by: Adriano Caloiaro <3331648+acaloiaro@users.noreply.github.com> * π 0.8.0 # [v0.8.0](v0.7.6...v0.8.0) (2022-12-27) ## β¨ New Features - [`6620f4c`](6620f4c) GoingToCamp Provider π (#99) (Issues: [`#99`](#99)) * π Lock File * Merge branch 'main' into tours Co-authored-by: Jingyuan Liang <jingyuanliang@google.com> Co-authored-by: semantic-release-bot <semantic-release-bot@martynus.net> Co-authored-by: Adriano Caloiaro <3331648+acaloiaro@users.noreply.github.com> Co-authored-by: Adriano Caloiaro <code@adriano.fyi>
This PR adds Going to Camp as a camply provider.
Addresses #94