edmundmok / mealpy Goto Github PK
View Code? Open in Web Editor NEWOrder your meals on MealPal automatically!
License: MIT License
Order your meals on MealPal automatically!
License: MIT License
Lines 110 to 114 in 2e35591
The credentials are only needed for login (one place) and only the http session cookie is persisted afterwards. These variables are in global namespace and are going to linger around longer than wanted. Probably even possible to inspect and pull values from a long-live scheduled process. Edit: this is non-security concern, discussed a bit in #15. Basically, this is no worse than using keyring or reading password from OS env or file on disk.
The scheduler was disabled during project boilerplate changes.
Lines 147 to 151 in 9e60e06
We'll want some way to allow user to run this adhoc or as scheduled task.
Let's add tests. More useful are the expected request response, having that schema or structure somewhere can make it easier to work on the code wihtout need to make a request every time. Mealpal responses also change based on time of day or week, when the "kitchen is closed", so this further unblocked development.
The schedules endpoint returns information for business hours. I think think this might be related to when the restaurant services mealpal orders:
The jsonpath is:
$.schedules[].restaurant.open
$.schedules[].restaurant.mpn_open
Lines 223 to 226 in 3d10eb6
This can be useful to prevent user from reserving during closed times. Also can be added to list restaurants
command output, so the user will have information to set up valid argument inputs.
In IRL, if a meal is unavailable, the user decides on their second choice. Many users will probably have a common fallback. We should support this by accepting a ranked preference of meals/restaurants. The retry logic will need to understand when a meal is sold out (vs. a http timeout) and to attempt to reserve the next choice.
I tried this out and it's works pretty well. I want to improve this and want to know if you are accepting PR or if I fork this and go off on my own.
Things this project needs:
Ideas I am thinking of:
Update README with instructions on how to use this script. This should wait until the code has stabilized first (probably sometime after 2019-04-05).
Use this template as a starting point.
Lines 1 to 2 in 2b7e674
The inputs to the script are hard-coded.
Lines 133 to 136 in 9e60e06
Add argparse to get these inputs.
When attempting to reserve a meal that's booked out, the response is HTTP 400, with response:
{
"error": "ERROR_AMOUNT_LIMIT"
}
It would be great handle this case, instead of retrying. Also will empower #9, since we can differentiate between when to retry and when to fallback to second choice.
Lines 129 to 130 in 5fc5bc7
FileNotFoundError
when running script:
python mealpy/mealpy.py reserve foo bar sf
Traceback (most recent call last):
File "mealpy/mealpy.py", line 229, in <module>
cli()
...
Snipped for brevity
...
File "mealpy/mealpy.py", line 138, in get_mealpal_credentials
config = load_config()
File "mealpy/mealpy.py", line 49, in load_config
copyfile(template_config_path, config_path)
File "/Users/ipwponies/repos/mealpy/venv/lib/python3.7/shutil.py", line 120, in copyfile
with open(src, 'rb') as fsrc:
FileNotFoundError: [Errno 2] No such file or directory: '/Users/ipwnponies/repos/mealpy/mealpy/config.template.yaml'
This was introduced in PR #20, whenmealpal.py
was moved to a package.
Build is broken. This was introduced when I added check-requirements
for #13 .
The issue is that ipython installs conditional dependencies based on OS platform and requirements-tools
doesn't handle this edge case. Options for fixing:
check-requirements
from make test
, maybe make it the responsibility of dev who updates requirements to run. It's only a sanity/safety checkpytest
We want the config feature to read a default config and then apply user customizations, similar to Hiera for Puppet. The config template is shipped with code and not intended to be modified, it serves as a template for users to copy and see all possible values. The the user's config is applied on top:
Line 55 in a580ab5
The bug is that this uses load_config_from_file
, which does shema validation, and will fail due to missing values. What we probably want to do instead is naively update
user's values and then rerun validation (or not, extra values should be ignored).
We could also have a minimal schema set for values the user must set. e.g. API tokens. But there's no use case for this yet, just dropping the thought for future reference.
next()
is used with no default, this will raise StopIteration
if not matched:
Lines 88 to 93 in a580ab5
The behaviour of early exit is fine (we can't fallback to another option if it's ambiguous). We probably want to default to None
, do truthy check , then print a a friendlier message to the user or raise a more meaningful error. This will be useful in the future, to do something like email the user when their meal could not be booked.
I discovered that no auth is required for getting city or menus. Likely only for POST calls, KITCHEN_URL
and RESERVATION_URL
.
I suggest we whitelist the URLs (operations) that require credential. This makes cli commands to list cities or menus (#7) simpler to test and run, since it's stateless and doesn't require requests
session or unnecessary logins.
We're starting to see more contributors and we have some tests. Let's set up TravisCI to automatically run tests on PRs, reduces the need to ask if they've ran unit tests, can instead focus on what manual verification was done.
@edmundmok, as the repository owner, can you enable TravisCI? From this stackoverflow post, I can do the rest of the setup via travis.yml
file.
Cache credentials so they don't need to be input every time.
This can either be the password (encrypted, not plaintext) or http session cookie. I'm not familiar with how cookies TTL work, although it might be enough if the cookie can persist for a few days.
Fix main thus, otherwise it does not get the password from the keyring:
if name == 'main':
EMAIL = load_config()['email_address']
if USE_KEYRING:
# If we're using keyring, we should always grab from keyring instead of holding on to potentially stale password
PASSWORD = keyring.get_password(KEYRING_SERVICENAME, EMAIL)
if not PASSWORD:
PASSWORD = getpass.getpass('Credential not yet stored in keychain, please enter password: ')
keyring.set_password(
KEYRING_SERVICENAME,
EMAIL,
PASSWORD)
else:
PASSWORD = getpass.getpass('Enter password: ')
We can cache the response of the restaurant/meal/hours queries. This will provide users ability to lookup possible inputs to provide as arguments.
Meals might be trickier, since they can change day-to-day. That can be a follow-up to this ticket, the benefit of getting reasonable inputs to provide to CLI arguments is great enough on its own.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.