Skip to content

Commit 5aed1b4

Browse files
committed
initial
1 parent 5d4136b commit 5aed1b4

File tree

6 files changed

+81
-149
lines changed

6 files changed

+81
-149
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
.idea
22
venv
33
build
4+
dist
45
*.pyc
56
*.spec
67
config.ini

KrogerAPI.py

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import asyncio
22
import json
33
import KrogerCLI
4-
import time
54
from pyppeteer import launch
65

76

@@ -28,10 +27,11 @@ def clip_coupons(self):
2827
async def _get_account_info(self):
2928
signed_in = await self.sign_in_routine()
3029
if not signed_in:
30+
await self.destroy()
3131
return None
3232

3333
self.cli.console.print('Loading profile info..')
34-
await self.page.goto('https://www.ralphs.com/accountmanagement/api/profile')
34+
await self.page.goto('https://www.' + self.cli.config['main']['domain'] + '/accountmanagement/api/profile')
3535
try:
3636
plain_text = await self.page.plainText()
3737
profile = json.loads(plain_text)
@@ -45,6 +45,7 @@ async def _get_account_info(self):
4545
async def _clip_coupons(self):
4646
signed_in = await self.sign_in_routine(redirect_url='/cl/coupons/', contains=['Coupons Clipped'])
4747
if not signed_in:
48+
await self.destroy()
4849
return None
4950

5051
js = """
@@ -53,17 +54,18 @@ async def _clip_coupons(self):
5354
let el = document.getElementsByClassName('kds-Button--favorable')[i];
5455
if (el !== undefined) {
5556
el.scrollIntoView();
56-
/*el.click();*/
57+
el.click();
5758
}
5859
}
5960
"""
6061

6162
self.cli.console.print('[italic]Applying the coupons, please wait..[/italic]')
6263
await self.page.keyboard.press('Escape')
63-
for i in range(5):
64+
for i in range(6):
6465
await self.page.evaluate(js)
6566
await self.page.keyboard.press('End')
66-
time.sleep(1)
67+
await self.page.waitFor(1000)
68+
await self.page.waitFor(3000)
6769
await self.destroy()
6870
self.cli.console.print('[bold]Coupons successfully clipped to your account! :thumbs_up:[/bold]')
6971

@@ -74,17 +76,16 @@ async def init(self):
7476
await self.page.setViewport({'width': 700, 'height': 0})
7577

7678
async def destroy(self):
77-
time.sleep(30)
7879
await self.browser.close()
7980

8081
async def sign_in_routine(self, redirect_url='/account/update', contains=None):
8182
await self.init()
8283
self.cli.console.print('[italic]Signing in.. (please wait, it might take awhile)[/italic]')
8384
signed_in = await self.sign_in(redirect_url, contains)
8485

85-
if not signed_in and not self.browser_options['headless']:
86+
if not signed_in and self.browser_options['headless']:
8687
self.cli.console.print('[red]Sign in failed. Trying one more time..[/red]')
87-
self.browser_options['headless'] = True
88+
self.browser_options['headless'] = False
8889
await self.destroy()
8990
await self.init()
9091
signed_in = await self.sign_in(redirect_url, contains)
@@ -99,7 +100,7 @@ async def sign_in(self, redirect_url, contains):
99100
timeout = 20000
100101
if not self.browser_options['headless']:
101102
timeout = 60000
102-
await self.page.goto('https://www.ralphs.com/signin?redirectUrl=' + redirect_url)
103+
await self.page.goto('https://www.' + self.cli.config['main']['domain'] + '/signin?redirectUrl=' + redirect_url)
103104
await self.page.type('#SignIn-emailInput', self.cli.username)
104105
await self.page.type('#SignIn-passwordInput', self.cli.password)
105106
await self.page.keyboard.press('Enter')

KrogerCLI.py

Lines changed: 56 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import configparser
22
import os
33
import click
4+
import time
45
from rich.console import Console
56
from rich.panel import Panel
67
from rich import box
@@ -21,36 +22,76 @@ def __init__(self):
2122
self.config.read(self.config_file)
2223
self.init()
2324

24-
def _write_config_file(self):
25-
with open(self.config_file, 'w') as f:
26-
self.config.write(f)
25+
def init(self):
26+
if self.config['profile']['first_name'] != '':
27+
self.console.print(Panel('[bold]Welcome Back, ' + self.config['profile']['first_name'] + '! :smiley:\n'
28+
'[dark_blue]Kroger[/dark_blue] CLI[/bold]', box=box.ASCII))
29+
else:
30+
self.console.print(Panel('[bold]Welcome to [dark_blue]Kroger[/dark_blue] CLI[/bold] (unofficial command '
31+
'line interface)', box=box.ASCII))
2732

28-
def _init_config_file(self):
29-
self.config.add_section('main')
30-
self.config['main']['username'] = ''
31-
self.config['main']['password'] = ''
32-
self.config.add_section('profile')
33-
self.config['profile']['first_name'] = ''
34-
self._write_config_file()
33+
self.prompt_store_selection()
3534

36-
def set_credentials(self, username, password):
37-
self.username = username
38-
self.password = password
35+
if self.username is None and self.config['main']['username'] != '':
36+
self.username = self.config['main']['username']
37+
self.password = self.config['main']['password']
38+
else:
39+
self.prompt_credentials()
3940

40-
def prompt_option(self):
41+
self.prompt_options()
42+
43+
def prompt_store_selection(self):
44+
pass
45+
# TODO:
46+
# self.console.print('Please select preferred store')
47+
48+
def prompt_credentials(self):
49+
self.console.print('In order to continue, please enter your username (email) and password for kroger.com '
50+
'(also works with Ralphs, Dillons, Smith’s and other Kroger’s Chains)')
51+
username = click.prompt('Username (email)')
52+
password = click.prompt('Password')
53+
self._set_credentials(username, password)
54+
55+
def prompt_options(self):
4156
while True:
4257
self.console.print('[bold]1[/bold] - Display account info')
4358
self.console.print('[bold]2[/bold] - Clip all digital coupons')
59+
self.console.print('[bold]8[/bold] - Re-Enter username/password')
4460
self.console.print('[bold]9[/bold] - Exit')
4561
option = click.prompt('Please select from one of the options', type=int)
4662

4763
if option == 1:
4864
self._option_account_info()
4965
elif option == 2:
5066
self._option_clip_coupons()
67+
elif option == 8:
68+
self.prompt_credentials()
5169
elif option == 9:
5270
return
5371

72+
self.console.rule()
73+
time.sleep(2)
74+
75+
def _write_config_file(self):
76+
with open(self.config_file, 'w') as f:
77+
self.config.write(f)
78+
79+
def _init_config_file(self):
80+
self.config.add_section('main')
81+
self.config['main']['username'] = ''
82+
self.config['main']['password'] = ''
83+
self.config['main']['domain'] = 'kroger.com'
84+
self.config.add_section('profile')
85+
self.config['profile']['first_name'] = ''
86+
self._write_config_file()
87+
88+
def _set_credentials(self, username, password):
89+
self.username = username
90+
self.password = password
91+
self.config['main']['username'] = self.username
92+
self.config['main']['password'] = self.password
93+
self._write_config_file()
94+
5495
def _option_account_info(self):
5596
info = self.api.get_account_info()
5697
if info is None:
@@ -67,25 +108,7 @@ def _option_account_info(self):
67108
self.config['profile']['state'] = info['address']['stateCode']
68109
self.config['profile']['zip'] = info['address']['zip']
69110
self._write_config_file()
70-
self.console.log(self.config.items(section='profile'))
111+
self.console.print(self.config.items(section='profile'))
71112

72113
def _option_clip_coupons(self):
73114
self.api.clip_coupons()
74-
75-
def _sign_in(self):
76-
if self.api.sign_in(self.username, self.password):
77-
self.config['main']['username'] = self.username
78-
self.config['main']['password'] = self.password
79-
self._write_config_file()
80-
return True
81-
else:
82-
self.console.print('[bold red]Incorrect username or password, please try again[/bold red]')
83-
return False
84-
85-
def init(self):
86-
self.console.print(Panel('[bold]Welcome to [dark_blue]Kroger[/dark_blue] CLI[/bold] (unofficial command line '
87-
'interface)', box=box.ASCII))
88-
89-
if self.username is None and self.config['main']['username'] != '':
90-
self.username = self.config['main']['username']
91-
self.password = self.config['main']['password']

create_executable.bat

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
call venv\scripts\activate
2+
3+
pyinstaller -n kroger-cli ^
4+
--onefile ^
5+
--exclude-module tkinter ^
6+
--hidden-import=six ^
7+
--hidden-import=packaging ^
8+
--hidden-import=packaging.version ^
9+
--hidden-import=packaging.requirements ^
10+
--hidden-import=packaging.specifiers ^
11+
--hidden-import=pkg_resources ^
12+
--hidden-import pkg_resources.py2_warn ^
13+
main.py

main.py

Lines changed: 1 addition & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,4 @@
11
from KrogerCLI import *
2-
import click
3-
# Required for pyinstaller
4-
import six
5-
import packaging
6-
import packaging.version
7-
import packaging.requirements
8-
import packaging.specifiers
9-
import pkg_resources
10-
11-
cli = KrogerCLI()
12-
13-
14-
@click.command()
15-
@click.option('--username', prompt=True)
16-
@click.option('--password', prompt=True)
17-
def prompt_credentials(username, password):
18-
cli.set_credentials(username, password)
19-
202

213
if __name__ == '__main__':
22-
if cli.username is None or cli.password is None:
23-
cli.console.print('In order to continue, please enter your username (email) and password')
24-
prompt_credentials()
25-
26-
cli.prompt_option()
4+
cli = KrogerCLI()

test.py

Lines changed: 0 additions & 84 deletions
This file was deleted.

0 commit comments

Comments
 (0)