chefmate 1.0.1__py3-none-any.whl → 1.0.2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
chefmate/chefmate_core.py CHANGED
@@ -27,6 +27,7 @@ from selenium.webdriver.common.by import By
27
27
  from selenium.webdriver.common.keys import Keys
28
28
  from chefmate.browser_manager import BrowserManager
29
29
  from selenium.webdriver.support.ui import WebDriverWait
30
+ from selenium.common.exceptions import TimeoutException
30
31
  from selenium.webdriver.support import expected_conditions as EC
31
32
  # ------------------------------------------------------------------
32
33
 
@@ -124,7 +125,12 @@ class ChefMate:
124
125
 
125
126
  def goto_dashboard(self):
126
127
  self.browser.driver.get("https://www.codechef.com/dashboard")
127
- WebDriverWait(self.browser.driver, 10).until(EC.presence_of_element_located((By.XPATH, "//img[contains(@alt, 'CodeChef Logo')]")))
128
+ try:
129
+ WebDriverWait(self.browser.driver, 15).until(
130
+ EC.presence_of_element_located((By.XPATH, "//img[contains(@alt, 'CodeChef Logo')]"))
131
+ )
132
+ except TimeoutException:
133
+ print(f"{Fore.RED} Failed to load dashboard page in 15seconds. Slow Internet \n")
128
134
  print(f"{Fore.GREEN} Dashboard opened successfully! \u2714\n")
129
135
 
130
136
  def display_logo(self):
@@ -175,6 +181,7 @@ class ChefMate:
175
181
  self.contest_id = None # Add this line to store the contest ID
176
182
  self.contest_dir = None # Add this line to store the contest directory
177
183
  self.problem_status = {}
184
+ self.logged_in = False
178
185
 
179
186
  def setup(self):
180
187
  """Setup ChefMate configuration"""
@@ -352,10 +359,13 @@ class ChefMate:
352
359
  dashboard_URL = "https://www.codechef.com/dashboard"
353
360
  self.browser.driver.get(dashboard_URL)
354
361
  try:
355
- WebDriverWait(self.browser.driver, 10).until(
362
+ WebDriverWait(self.browser.driver, 15).until(
356
363
  EC.presence_of_element_located((By.XPATH, "//img[contains(@alt, 'CodeChef Logo') ]"))
357
364
  )
358
365
  return self.browser.driver.current_url == dashboard_URL
366
+ except TimeoutException:
367
+ print(f"{Fore.RED} Failed to load dashboard page in 15seconds. Slow Internet \n")
368
+ return False
359
369
  except: return False
360
370
 
361
371
  def login(self, first_login: bool = False):
@@ -367,6 +377,7 @@ class ChefMate:
367
377
 
368
378
  if self.already_logged_in():
369
379
  print(f"{Fore.GREEN} Already logged in \u2714\n")
380
+ self.logged_in = True
370
381
  return True
371
382
 
372
383
  username = self.config.get("username", "")
@@ -382,15 +393,23 @@ class ChefMate:
382
393
  self.browser.driver.get("https://www.codechef.com/login")
383
394
  self.type_writer(" Loggin in ... ")
384
395
 
385
- WebDriverWait(self.browser.driver, 10).until(
386
- EC.element_to_be_clickable((By.ID, "edit-name"))
387
- )
396
+ try:
397
+ WebDriverWait(self.browser.driver, 15).until(
398
+ EC.element_to_be_clickable((By.ID, "edit-name"))
399
+ )
400
+ except TimeoutException:
401
+ print(f"{Fore.RED} Failed to load login page in 15seconds. Slow Internet, Please Try again\n")
402
+ return False
388
403
 
389
404
  if first_login:
390
405
  self.browser.driver.refresh()
391
- WebDriverWait(self.browser.driver, 10).until(
392
- EC.element_to_be_clickable((By.ID, "edit-name"))
393
- )
406
+ try:
407
+ WebDriverWait(self.browser.driver, 15).until(
408
+ EC.element_to_be_clickable((By.ID, "edit-name"))
409
+ )
410
+ except TimeoutException:
411
+ print(f"{Fore.RED} Failed to load login page in 15seconds. Slow Internet, Please Try again\n")
412
+ return False
394
413
 
395
414
  u_box = self.browser.driver.find_element(By.ID, "edit-name")
396
415
  u_box.send_keys(Keys.CONTROL + "a" + Keys.BACKSPACE)
@@ -401,7 +420,7 @@ class ChefMate:
401
420
  p_box.send_keys(password + Keys.RETURN)
402
421
 
403
422
  max_wait_time = 20
404
- interval = 2
423
+ interval = 5
405
424
  elapsed_time = 0
406
425
 
407
426
  # For slow networks, retry login
@@ -411,6 +430,7 @@ class ChefMate:
411
430
  EC.element_to_be_clickable((By.XPATH, "//div[contains(@class, '_content__container')]")
412
431
  ))
413
432
  print(f"{Fore.GREEN} Successfully loaded Dashboard \u2714\n{Style.RESET_ALL}")
433
+ self.logged_in = True
414
434
  return True
415
435
  except:
416
436
  elapsed_time += interval
@@ -425,18 +445,25 @@ class ChefMate:
425
445
  if not self.browser.driver:
426
446
  print(f"{Fore.YELLOW} No active browser session.\n")
427
447
  return
428
-
448
+
429
449
  self.type_writer(" Logging out ... ")
430
450
 
431
451
  self.browser.driver.get("https://www.codechef.com/logout")
432
452
  try:
433
- WebDriverWait(self.browser.driver, 10).until(
453
+ WebDriverWait(self.browser.driver, 15).until(
434
454
  EC.presence_of_element_located((By.XPATH, "//img[contains(@alt, 'CodeChef Logo')]"))
435
455
  )
436
456
  print(f"{Fore.GREEN} Logged out successfully \u2714\n")
457
+ self.logged_in = False
458
+ return
459
+ except TimeoutException:
460
+ print(f"{Fore.RED} Logout timed out, has waited 15 seconds. Please check your internet connection and try again.\n")
461
+ return
437
462
  except:
438
463
  print(f"{Fore.YELLOW} Logout status unclear, closing browser anyway.\n")
439
-
464
+ self.logged_in = False
465
+ return
466
+
440
467
  def quit(self):
441
468
  """Quit the browser and end session"""
442
469
  if self.browser.driver:
@@ -452,8 +479,10 @@ class ChefMate:
452
479
  Prompts for contest ID and division, opens contest page and all problem tabs.
453
480
  """
454
481
 
455
- if not self.already_logged_in():
456
- self.login()
482
+ if not self.logged_in:
483
+ self.type_writer(" Logging in before opening contest ... ")
484
+ if not self.login():
485
+ return False
457
486
 
458
487
  division_map = {1: 'A', 2: 'B', 3: 'C', 4: 'D'}
459
488
 
@@ -470,9 +499,11 @@ class ChefMate:
470
499
 
471
500
  self.browser.driver.get(contest_url)
472
501
  try:
473
- WebDriverWait(self.browser.driver, 10).until(
502
+ WebDriverWait(self.browser.driver, 15).until(
474
503
  EC.element_to_be_clickable((By.XPATH, "//div[contains(@class, 'problem-table')]"))
475
504
  )
505
+ except TimeoutException:
506
+ print(f"{Fore.RED} Failed to load problems in 15seconds. Slow Internet, Please Try again\n")
476
507
  except:
477
508
  print(f"{Fore.YELLOW} Contest page looks different than expected, but continuing...")
478
509
 
@@ -483,6 +514,8 @@ class ChefMate:
483
514
  EC.presence_of_element_located((By.CLASS_NAME, "dataTable"))
484
515
  )
485
516
  links = table.find_elements(By.TAG_NAME, "a")
517
+ except TimeoutException:
518
+ print(f"{Fore.RED} Failed to load problems in 10seconds. Slow Internet, Please Try again\n")
486
519
  except:
487
520
  links = self.browser.driver.find_elements(By.XPATH, "//a[contains(@href, 'problems')]")
488
521
 
@@ -575,7 +608,7 @@ class ChefMate:
575
608
  except Exception as e:
576
609
  print(f"{Fore.RED} Error selecting language: {e}")
577
610
  return False
578
-
611
+
579
612
  def _load_code(self, code_text):
580
613
  """Load code into editor"""
581
614
  try:
@@ -606,12 +639,6 @@ class ChefMate:
606
639
  def submit_solution(self, problem_num: int = None):
607
640
  # Submit solution for a problem
608
641
 
609
- curr_url = self.browser.driver.current_url
610
- if not self.login():
611
- self.login()
612
-
613
- self.browser.driver.get(curr_url)
614
-
615
642
  if not self.problems or not self.tabs:
616
643
  print(f"{Fore.RED} No problems loaded. Please open contest tab first.")
617
644
  return False
@@ -656,9 +683,18 @@ class ChefMate:
656
683
  text_input.send_keys(Keys.CONTROL + Keys.ENTER)
657
684
  self.type_writer(" Submitting the Code ... ")
658
685
 
659
- WebDriverWait(self.browser.driver, 20).until(
660
- EC.presence_of_element_located((By.XPATH, "//div[contains(@class, '_run__container')]"))
661
- )
686
+ try:
687
+ WebDriverWait(self.browser.driver, 20).until(
688
+ EC.presence_of_element_located((By.XPATH, "//div[contains(@class, '_run__container')]"))
689
+ )
690
+ except TimeoutException:
691
+ print(f"{Fore.RED} Submission timed out, has waited 20 seconds. Please check your internet connection and try again.\n")
692
+ return False
693
+ except Exception as e:
694
+ print(f"{Fore.RED} Error submitting code: {e}")
695
+ return False
696
+
697
+ # Wait for the verdict to appear
662
698
 
663
699
  verdict_in_run_container = self.browser.driver.find_element(By.XPATH, "//div[contains(@class, '_run__container')]").text
664
700
  if 'Error' in verdict_in_run_container or 'limit' in verdict_in_run_container.lower():
@@ -666,9 +702,16 @@ class ChefMate:
666
702
  return False
667
703
 
668
704
  # Wait for the verdict table to appear
669
- WebDriverWait(self.browser.driver, 20).until(
670
- EC.presence_of_element_located((By.XPATH, "//table[contains(@class, 'status-table')]"))
671
- )
705
+ try:
706
+ WebDriverWait(self.browser.driver, 20).until(
707
+ EC.presence_of_element_located((By.XPATH, "//table[contains(@class, 'status-table')]"))
708
+ )
709
+ except TimeoutException:
710
+ print(f"{Fore.RED} Submission timed out, has waited 20 seconds. Please check your internet connection and try again.\n")
711
+ return False
712
+ except Exception as e:
713
+ print(f"{Fore.RED} Error submitting code: {e}")
714
+ return False
672
715
 
673
716
  # Extract table data
674
717
  table_element = self.browser.driver.find_element(By.XPATH, "//table[contains(@class, 'status-table')]")
@@ -814,9 +857,16 @@ class ChefMate:
814
857
  try:
815
858
  text_input = self.browser.driver.find_element(By.CSS_SELECTOR, "textarea.ace_text-input")
816
859
  text_input.send_keys(Keys.CONTROL + Keys.SHIFT + Keys.ENTER)
817
- WebDriverWait(self.browser.driver, 20).until(
818
- EC.presence_of_element_located((By.XPATH, "//div[contains(@class, '_output-item__value_')]"))
819
- )
860
+ try:
861
+ WebDriverWait(self.browser.driver, 20).until(
862
+ EC.presence_of_element_located((By.XPATH, "//div[contains(@class, '_output-item__value_')]"))
863
+ )
864
+ except TimeoutException:
865
+ print(f"{Fore.RED} Timed out waiting for test cases to run.")
866
+ return False
867
+ except Exception as e:
868
+ print(f"{Fore.RED} Error waiting for test cases to run: {e}")
869
+ return False
820
870
  except Exception as e:
821
871
  print(f"{Fore.RED} Error running test cases: {e}")
822
872
  return False
chefmate/cli.py CHANGED
@@ -38,68 +38,13 @@ def loading_animation(stop_event):
38
38
  def clear_terminal():
39
39
  """Clears the terminal screen based on the OS"""
40
40
  os.system('cls' if platform.system() == 'Windows' else 'clear')
41
- print(f"{Fore.GREEN} Terminal cleared successfully! \u2714\n")
41
+ print(f"{Fore.GREEN} Terminal cleared successfully! ✔\n")
42
42
 
43
43
  @click.group()
44
44
  def cli():
45
45
  """ChefMate - CodeChef Automation Tool"""
46
46
  pass
47
47
 
48
- @cli.command()
49
- def setup():
50
- """Configure ChefMate settings"""
51
- cm = ChefMate()
52
- cm.setup()
53
-
54
- @cli.command()
55
- def login():
56
- """Login to CodeChef"""
57
- cm = ChefMate()
58
- if cm.initialize():
59
- cm.login()
60
- else:
61
- click.echo(f"{Fore.RED} Failed to initialize browser.")
62
-
63
- @cli.command()
64
- def logout():
65
- """Logout from CodeChef"""
66
- cm = ChefMate()
67
- if cm.initialize():
68
- cm.logout()
69
- else:
70
- click.echo(f"{Fore.RED} Failed to initialize browser.")
71
-
72
- @cli.command()
73
- @click.option('--problem', '-p', type=int, help='Problem number to check')
74
- def check(problem):
75
- """Check sample test cases for a problem"""
76
- cm = ChefMate()
77
- if cm.initialize() and cm.login():
78
- if cm.open_contest():
79
- cm.demo_cases_check(problem)
80
- else:
81
- click.echo(f"{Fore.RED} Failed to initialize session.")
82
-
83
- @cli.command()
84
- @click.option('--problem', '-p', type=int, help='Problem number to submit')
85
- def submit(problem):
86
- """Submit solution for a problem"""
87
- cm = ChefMate()
88
- if cm.initialize() and cm.login():
89
- if cm.open_contest():
90
- cm.submit_solution(problem)
91
- else:
92
- click.echo(f"{Fore.RED} Failed to initialize session.")
93
-
94
- @cli.command()
95
- def contest():
96
- """Open a contest and load problems"""
97
- cm = ChefMate()
98
- if cm.initialize() and cm.login():
99
- cm.open_contest()
100
- else:
101
- click.echo(f"{Fore.RED} Failed to initialize session.")
102
- # -------------------- Interactive Mode ------------------
103
48
  @cli.command()
104
49
  def interactive():
105
50
  """Run ChefMate in interactive mode"""
@@ -161,31 +106,35 @@ def interactive():
161
106
  choice = inquirer.select(
162
107
  message="Select an option: ",
163
108
  choices=quest_list,
164
- default=current_choice, # Use the stored current choice
165
- qmark="", # Remove the default [?]
166
- pointer=">", # Custom arrow pointer
109
+ default=current_choice,
110
+ qmark="",
111
+ pointer=">",
167
112
  instruction="(Use arrow keys to navigate)"
168
113
  ).execute()
169
114
 
170
- # Update the current choice for next iteration
171
115
  current_choice = choice
172
116
 
173
117
  print("\033[F\033[2K", end="")
174
118
  selected_name = next((c.name for c in quest_list if c.value == choice), choice)
175
119
  table = Table(show_header=False, box=box.ROUNDED, border_style='green')
176
-
177
- # Create a Text object with styling for selected name
178
120
  styled_text = Text("You Selected: ")
179
121
  styled_text.append(selected_name, style="cyan")
180
-
181
122
  table.add_row(styled_text)
182
123
  console.print(table)
183
124
 
184
125
  if choice == '_login':
185
- if first_login:
186
- cm.login(first_login=True)
126
+ if first_login: cm.login(first_login=True)
187
127
  else: cm.login()
188
- elif choice == '_logout': cm.logout()
128
+ elif choice == '_logout':
129
+ if cm.tabs and len(cm.tabs) > 1:
130
+ cm.browser.driver.switch_to.window(cm.tabs[0])
131
+ for tab in cm.tabs[1:]:
132
+ cm.browser.driver.switch_to.window(tab)
133
+ cm.browser.driver.close()
134
+ cm.tabs = [cm.tabs[0]]
135
+ cm.browser.driver.switch_to.window(cm.tabs[0])
136
+ print(f"{Fore.GREEN} Closed contest tabs successfully! ✔")
137
+ cm.logout()
189
138
  elif choice == '_config': cm.setup()
190
139
  elif choice == '_clear': clear_terminal()
191
140
  elif choice == '_contest_ini':
@@ -202,74 +151,57 @@ def interactive():
202
151
  cm.quit()
203
152
  break
204
153
  elif choice == '_log_and_ex':
154
+ if cm.tabs and len(cm.tabs) > 1:
155
+ cm.browser.driver.switch_to.window(cm.tabs[0])
156
+ for tab in cm.tabs[1:]:
157
+ cm.browser.driver.switch_to.window(tab)
158
+ cm.browser.driver.close()
159
+ cm.tabs = [cm.tabs[0]]
160
+ cm.browser.driver.switch_to.window(cm.tabs[0])
161
+ print(f"{Fore.GREEN} All tabs closed successfully! ✔")
205
162
  cm.logout()
206
163
  cm.quit()
207
164
  break
208
165
  elif choice == '_close_curr_cont':
209
- # Close all problem tabs
210
166
  if cm.tabs and len(cm.tabs) > 1:
211
167
  cm.browser.driver.switch_to.window(cm.tabs[0])
212
-
213
168
  for tab in cm.tabs[1:]:
214
169
  cm.browser.driver.switch_to.window(tab)
215
170
  cm.browser.driver.close()
216
-
217
171
  cm.tabs = [cm.tabs[0]]
218
172
  cm.browser.driver.switch_to.window(cm.tabs[0])
219
- print(f"{Fore.GREEN} Closed contest tabs successfully! \u2714")
220
-
173
+ print(f"{Fore.GREEN} Closed contest tabs successfully! ")
221
174
  dashboard_text = " Loading Dashboard now ..."
222
175
  for char in dashboard_text:
223
176
  sys.stdout.write(Fore.YELLOW + char)
224
177
  sys.stdout.flush()
225
178
  time.sleep(0.04)
226
-
227
179
  sys.stdout.write('\n')
228
180
  cm.goto_dashboard()
229
-
230
181
  quest_list.pop(4)
231
182
  quest_list.pop(3)
232
183
  quest_list.insert(3, Choice(value="_contest_ini", name="Open Contest"))
233
-
234
- # Reset problems list
235
184
  cm.problems = []
236
-
237
- # Reset contest ID and directory
238
185
  cm.contest_id = None
239
186
  cm.contest_dir = None
240
187
  elif choice == '_track_problelm':
241
188
  cm.show_tracker()
242
189
  elif choice == '_contest_again':
243
- # Close all problem tabs except the first one (contest page)
244
190
  if cm.tabs and len(cm.tabs) > 1:
245
- # Switch to first tab (contest page)
246
191
  cm.browser.driver.switch_to.window(cm.tabs[0])
247
-
248
- # Close all problem tabs
249
192
  for tab in cm.tabs[1:]:
250
193
  cm.browser.driver.switch_to.window(tab)
251
194
  cm.browser.driver.close()
252
-
253
- # Reset tabs list to only include the first tab
254
195
  cm.tabs = [cm.tabs[0]]
255
196
  cm.browser.driver.switch_to.window(cm.tabs[0])
256
- print(f"{Fore.GREEN} Closed previous contest tabs successfully! \u2714")
257
-
258
- # Reset problems list
197
+ print(f"{Fore.GREEN} Closed previous contest tabs successfully! ")
259
198
  cm.problems = []
260
-
261
- # Reset contest ID and directory
262
199
  cm.contest_id = None
263
200
  cm.contest_dir = None
264
-
265
- # Open new contest
266
201
  cm.open_contest()
267
202
  else: click.echo(f"{Fore.RED} Invalid choice!")
268
- # --------------------------------------------------------
269
203
 
270
204
  cli.add_command(interactive)
271
205
 
272
- # ------ Main Script -------
273
206
  if __name__ == "__main__":
274
207
  interactive()
275
- # --------------------------
@@ -0,0 +1,136 @@
1
+ Metadata-Version: 2.4
2
+ Name: chefmate
3
+ Version: 1.0.2
4
+ Summary: Automation tool for CodeChef
5
+ Home-page: https://github.com/Anuj-72/ChefMate
6
+ Author: Anuj Kumar Sah
7
+ Author-email: Anuj Kumar Sah <anujsah282005@gmail.com>
8
+ License: MIT
9
+ Keywords: CodeChef,CLI,automation,competitive-programming
10
+ Classifier: Programming Language :: Python :: 3
11
+ Classifier: License :: OSI Approved :: MIT License
12
+ Classifier: Operating System :: OS Independent
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: Topic :: Software Development :: Build Tools
15
+ Requires-Python: >=3.7
16
+ Description-Content-Type: text/markdown
17
+ License-File: LICENSE
18
+ Dynamic: author
19
+ Dynamic: home-page
20
+ Dynamic: license-file
21
+ Dynamic: requires-python
22
+
23
+ # ChefMate
24
+
25
+ ![Logo](assets/CHEFMATE.png)
26
+
27
+ ChefMate is a CLI tool for automating CodeChef tasks via an interactive menu-driven interface. It streamlines the workflow of logging in, opening contests, solving problems, running demo test cases, submitting solutions, and tracking problem statuses in real time.
28
+
29
+ ## Features
30
+
31
+ - **Interactive Mode**: User-friendly, arrow-key-driven menu
32
+ - **Automated Login**: Seamlessly sign into CodeChef
33
+ - **Contest Management**: Open contests by ID directly in browser
34
+ - **Problem Solving Support**: Scaffold and open solution files locally
35
+ - **Demo Test Case Checking**: Run and verify sample tests before submission
36
+ - **Automated Submission**: Submit solutions without leaving the terminal
37
+ - **Problem Tracker**: View status (✅ done | 🟡 pending | ❌ wrong)
38
+ - **Configuration Management**: Easily reconfigure user preferences
39
+ - **Clear Terminal**: Wipe the screen for a fresh view
40
+
41
+ ## Installation
42
+
43
+ You don’t need to clone any repository — just install via pip:
44
+
45
+ ```bash
46
+ pip install chefmate
47
+ ```
48
+
49
+ That’s it!
50
+
51
+ ## Usage
52
+
53
+ Run ChefMate in interactive mode:
54
+
55
+ ```bash
56
+ python main.py interactive
57
+ ```
58
+
59
+ > If you have set up an entry point, you can also run:
60
+
61
+ ```bash
62
+ chefmate interactive
63
+ ```
64
+
65
+ ## Initial Configuration
66
+
67
+ On first run, ChefMate will prompt you to configure key settings:
68
+
69
+ - **Username**: Your CodeChef username
70
+ - **Password**: Your CodeChef password (input hidden)
71
+ - **Default Solution Path**: Local directory or file path pattern for solutions
72
+ - **Chrome User Data Directory** (optional): Path to Chrome profile data
73
+ - **Chrome Profile** (optional): Profile name within Chrome
74
+ - **Preferred Language**: Language for submissions (C++, Python 3, Java, etc.)
75
+ - **Preferred Editor**: Editor to open solution files (default, VS Code, Sublime, etc.)
76
+
77
+ ![First Configure](assets/First_Configure.gif)
78
+
79
+ ## Interactive Mode Options
80
+
81
+ When you launch interactive mode, you’ll see a menu:
82
+
83
+ ```text
84
+ ==================================================
85
+ ChefMate Interactive Mode
86
+ ==================================================
87
+ ```
88
+
89
+ Use arrow keys to navigate and Enter to select any of the following:
90
+
91
+ | Option | Description | Example GIF/Screenshot |
92
+ |--------------------------------|-------------------------------------------------------|---------------------------------------------|
93
+ | **Login** | Authenticate with CodeChef | ![Logging In](assets/Logging_In.gif) |
94
+ | **Open Contest** | Open a CodeChef contest by ID in your browser | ![Open Contest](assets/Open_Contest_Page.gif) |
95
+ | **Solve Problems** | Scaffold and open solution templates locally | ![Solve Problems](assets/Solve_Problems.gif) |
96
+ | **Check Demo test cases** | Run sample tests on your solution | ![Demo Tests](assets/Demo_Test_Cases.gif) |
97
+ | **Submit Solution** | Submit your solution to CodeChef | ![Submitting Solution](assets/Submitting_Solution.gif) |
98
+ | **Problem Tracker** | View current status of each problem | ![Tracker](assets/Problem_Tracker.png) |
99
+ | **Re-configure ChefMate** | Update any configuration options | |
100
+ | **Clear Terminal** | Clear your terminal screen | |
101
+ | **Logout** | Sign out of your CodeChef session | |
102
+ | **Exit / Logout and Exit** | Quit interactive mode (and logout if selected) | |
103
+
104
+ ## Visual Walkthrough
105
+
106
+ ### Start ChefMate
107
+
108
+ ![Start ChefMate](assets/Start_ChefMate.gif)
109
+
110
+ ### Logging In
111
+
112
+ ![Logging In](assets/Logging_In.gif)
113
+
114
+ ### Opening a Contest
115
+
116
+ ![Open Contest](assets/Open_Contest_Page.gif)
117
+
118
+ ### Solving Problems
119
+
120
+ ![Solve Problems](assets/Solve_Problems.gif)
121
+
122
+ ### Checking Demo Test Cases
123
+
124
+ ![Demo Test Cases](assets/Demo_Test_Cases.gif)
125
+
126
+ ### Submitting a Solution
127
+
128
+ ![Submitting Solution](assets/Submitting_Solution.gif)
129
+
130
+ ### Problem Tracker
131
+
132
+ ![Problem Tracker](assets/Problem_Tracker.png)
133
+
134
+ ## License
135
+
136
+ This project is released under the MIT License. See [LICENSE](LICENSE) for details.
@@ -0,0 +1,10 @@
1
+ chefmate/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
+ chefmate/browser_manager.py,sha256=V1khfGVj8aeOmuQmVZLHs5H56vZRvtI97-nNe6pTK6E,2866
3
+ chefmate/chefmate_core.py,sha256=WlVAb20animW0RsgeDxep2TNslWRTSEylHnlrZFMClg,72178
4
+ chefmate/cli.py,sha256=qHVlNukl7vjEVXzdCJRT38XtbhaXCmcRUe4D3DAqBsE,7706
5
+ chefmate/config.py,sha256=itkFruFKMX7eday8UnAYOfnVMthivn20tiTlG87czyA,2220
6
+ chefmate-1.0.2.dist-info/licenses/LICENSE,sha256=dBIqGYz89ZL5FXsfdbOvpsPupYvcJfnkimw2vD7jZ94,1090
7
+ chefmate-1.0.2.dist-info/METADATA,sha256=76xTW6WEYRQDV3WEGGd_5314I7KUm4CdQtmlgI2wx-E,5240
8
+ chefmate-1.0.2.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
9
+ chefmate-1.0.2.dist-info/top_level.txt,sha256=jOlvGtNNEYlsbwLBD2lpAmZBSo1wq2dydfAM1lP_Ago,9
10
+ chefmate-1.0.2.dist-info/RECORD,,
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) [2025] [Anuj Kumar Sah]
3
+ Copyright (c) 2025 Anuj Kumar Sah
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
@@ -1,313 +0,0 @@
1
- Metadata-Version: 2.4
2
- Name: chefmate
3
- Version: 1.0.1
4
- Summary: A CodeChef automation CLI tool
5
- Home-page: https://github.com/Anuj-72/ChefMate
6
- Author: Anuj Kumar Sah
7
- Author-email: anujsah282005@gmail.com
8
- Classifier: Programming Language :: Python :: 3
9
- Classifier: License :: OSI Approved :: MIT License
10
- Classifier: Operating System :: OS Independent
11
- Requires-Python: >=3.7
12
- Description-Content-Type: text/markdown
13
- License-File: LICENSE
14
- Requires-Dist: selenium
15
- Requires-Dist: webdriver-manager
16
- Requires-Dist: click
17
- Requires-Dist: colorama
18
- Requires-Dist: inquirer
19
- Requires-Dist: InquirerPy
20
- Requires-Dist: rich
21
- Requires-Dist: tabulate
22
- Requires-Dist: pandas
23
- Dynamic: author
24
- Dynamic: author-email
25
- Dynamic: classifier
26
- Dynamic: description
27
- Dynamic: description-content-type
28
- Dynamic: home-page
29
- Dynamic: license-file
30
- Dynamic: requires-dist
31
- Dynamic: requires-python
32
- Dynamic: summary
33
-
34
- # ChefMate
35
-
36
- ChefMate is an automation tool designed to simplify and streamline your CodeChef contest participation. It leverages browser automation (using Selenium and ChromeDriver) along with a versatile command-line interface (CLI) to handle tasks such as logging in, contest management, problem scraping, solution submissions, and demo test case validations. ChefMate also helps set up directories and template files so that you can focus on solving problems quickly and efficiently.
37
-
38
- ---
39
-
40
- ## Table of Contents
41
-
42
- - [Introduction](#introduction)
43
- - [Features](#features)
44
- - [Architecture and Code Structure](#architecture-and-code-structure)
45
- - [Browser Manager (`browser_manager.py`)](#browser-manager)
46
- - [Core Functionality (`chefmate_core.py`)](#core-functionality)
47
- - [Command Line Interface (`cli.py`)](#command-line-interface)
48
- - [Configuration Management (`config.py`)](#configuration-management)
49
- - [Installation](#installation)
50
- - [Usage](#usage)
51
- - [Setup](#setup)
52
- - [Login and Logout](#login-and-logout)
53
- - [Contest and Problem Management](#contest-and-problem-management)
54
- - [Testing and Submissions](#testing-and-submissions)
55
- - [Interactive Mode](#interactive-mode)
56
- - [Dependencies](#dependencies)
57
- - [Troubleshooting](#troubleshooting)
58
- - [Future Improvements](#future-improvements)
59
- - [License](#license)
60
-
61
- ---
62
-
63
- ## Introduction
64
-
65
- ChefMate is built to help competitive programmers who participate in CodeChef contests. By automating several routine tasks (such as logging in, opening contest pages, fetching problems, and managing solution submissions), ChefMate removes friction from the contest environment. With its modular design, the tool offers easy configurability and a friendly CLI interface, making the CodeChef contest experience smoother and more productive.
66
-
67
- ---
68
-
69
- ## Features
70
-
71
- - **Browser Management:**
72
- - Detects and prevents conflicts with existing Chrome sessions.
73
- - Initializes a ChromeDriver with custom profiles and directories.
74
- - Configurable options to bypass common Chrome logging and automation detections.
75
-
76
- - **Automated Contest Interaction:**
77
- - Logs into CodeChef and navigates to the contest dashboard.
78
- - Opens contest pages and scrapes problem links and details.
79
- - Provides an interactive problem tracker to monitor submission statuses.
80
-
81
- - **Solution Management:**
82
- - Creates and manages solution directories for contests.
83
- - Generates template solution files in your preferred programming language.
84
- - Facilitates opening solution files in your favorite code editor.
85
-
86
- - **Submission and Testing:**
87
- - Automates the process of selecting the language from the CodeChef UI.
88
- - Loads solutions from files and submits them via the browser.
89
- - Runs sample test cases to verify outputs before actual submission.
90
- - Displays detailed verdict tables and highlights errors.
91
-
92
- - **Command-Line Interface (CLI):**
93
- - Offers a range of commands (setup, login, logout, contest, submit, check, interactive mode).
94
- - Provides an intuitive interactive mode with a clear menu-driven experience.
95
- - Uses libraries such as Click and InquirerPy for enhanced user interaction.
96
-
97
- - **Configuration Management:**
98
- - Manages user settings (username, password, solution paths, preferred language, Chrome profile, editor preferences) through a JSON configuration file stored in the user's home directory.
99
- - Ensures persistence and easy updates of user configuration.
100
-
101
- ---
102
-
103
- ## Architecture and Code Structure
104
-
105
- ChefMate’s code is organized into four main modules:
106
-
107
- ### Browser Manager
108
-
109
- **File:** `browser_manager.py`
110
-
111
- - **Purpose:**
112
- Manages the Chrome browser session using Selenium WebDriver.
113
- - **Key Functions:**
114
- - **Initialization:** Sets up the ChromeDriver with options such as user-data-dir and profile-directory for isolated sessions.
115
- - **Conflict Detection:** Checks if a Chrome instance is already running and prompts the user accordingly.
116
- - **Session Management:** Provides methods to initialize, operate, and close the browser session.
117
- - **Highlights:**
118
- Uses `webdriver_manager` to ensure the correct ChromeDriver is installed and employs custom options to reduce unwanted automation flags.
119
-
120
- ### Core Functionality
121
-
122
- **File:** `chefmate_core.py`
123
-
124
- - **Purpose:**
125
- Acts as the primary interface to ChefMate functionality. It integrates browser automation with the CodeChef website.
126
- - **Components:**
127
- - **Login/Logout:**
128
- Automates the CodeChef login procedure including form filling, waiting for dashboard elements, and handling potential errors.
129
- - **Contest Handling:**
130
- Opens a contest page, scrapes all available problem links, and dynamically creates a problem tracker.
131
- - **Solution Handling:**
132
- Searches for or prompts for the correct solution file. Generates solution templates based on the preferred programming language.
133
- - **Submission and Testing:**
134
- Provides mechanisms to load code into the CodeChef code editor, submit solutions, and analyze output results by parsing verdict tables.
135
- - **Interactive Utilities:**
136
- Functions like typewriter text effects, dashboard redirection, and dynamic problem tracking to enhance the user experience.
137
-
138
- ### Command Line Interface
139
-
140
- **File:** `cli.py`
141
-
142
- - **Purpose:**
143
- Provides a user-friendly CLI to interact with ChefMate.
144
- - **Features:**
145
- - **CLI Commands:**
146
- Implements commands using Click. Commands include `setup`, `login`, `logout`, `check`, `submit`, `contest`, and `interactive`.
147
- - **Interactive Mode:**
148
- An extended menu-driven interface built using InquirerPy that lets users select among different operational modes such as logging in, solving problems, or reconfiguring settings.
149
- - **UI Enhancements:**
150
- Uses the Rich library for improved terminal output, such as styled tables and animated loaders.
151
-
152
- ### Configuration Management
153
-
154
- **File:** `config.py`
155
-
156
- - **Purpose:**
157
- Handles persistent configurations for ChefMate by reading from and writing to a JSON file.
158
- - **Details:**
159
- - **Default Configuration:**
160
- Automatically creates a configuration file in the user's home directory (`~/.chefmate/config.json`) if it does not exist.
161
- - **Dynamic Updates:**
162
- Offers methods to get, set, and update various settings including username, password, preferred language, solution file paths, and Chrome user data directories.
163
- - **Robustness:**
164
- Includes error handling to recreate a default configuration if the current configuration file is corrupted.
165
-
166
- ---
167
-
168
- ## Installation
169
-
170
- 1. **Clone the Repository:**
171
-
172
- ```bash
173
- git clone https://github.com/yourusername/chefmate.git
174
- cd chefmate
175
- ```
176
-
177
- 2. **Set Up a Python Virtual Environment (Optional but Recommended):**
178
-
179
- ```bash
180
- python -m venv venv
181
- source venv/bin/activate # Linux/Mac
182
- venv\Scripts\activate # Windows
183
- ```
184
-
185
- 3. **Install Dependencies:**
186
-
187
- ChefMate relies on several Python packages. Install them using:
188
-
189
- ```bash
190
- pip install -r requirements.txt
191
- ```
192
-
193
- > **Note:** Dependencies include libraries like Selenium, webdriver-manager, Click, InquirerPy, Rich, and Colorama. Make sure your environment meets the prerequisites for Selenium and ChromeDriver.
194
-
195
- ---
196
-
197
- ## Usage
198
-
199
- ### Setup
200
-
201
- Run the setup command to configure ChefMate with your CodeChef credentials, preferred language, editor, and solution file path:
202
-
203
- ```bash
204
- python cli.py setup
205
- ```
206
-
207
- ### Login and Logout
208
-
209
- To login to CodeChef, use:
210
-
211
- ```bash
212
- python cli.py login
213
- ```
214
-
215
- And to logout:
216
-
217
- ```bash
218
- python cli.py logout
219
- ```
220
-
221
- ### Contest and Problem Management
222
-
223
- - **Opening a Contest:**
224
- Launch a contest by providing the contest ID and your division using:
225
-
226
- ```bash
227
- python cli.py contest
228
- ```
229
-
230
- - **Automatic Problem Scraping:**
231
- ChefMate will automatically identify and open all the contest problem tabs and display a problem tracker.
232
-
233
- ### Testing and Submissions
234
-
235
- - **Check Demo Test Cases:**
236
- Validate your solution using sample test cases:
237
-
238
- ```bash
239
- python cli.py check --problem 1
240
- ```
241
-
242
- - **Submitting a Solution:**
243
- To submit your solution for a given problem:
244
-
245
- ```bash
246
- python cli.py submit --problem 1
247
- ```
248
-
249
- - **Solving Problems (Template Generation & File Management):**
250
- ChefMate automatically generates solution template files in a designated contest directory for you to edit. It opens the selected file in your preferred text editor.
251
-
252
- ### Interactive Mode
253
-
254
- ChefMate also offers an interactive mode that provides a dynamic menu for operations. Launch it with:
255
-
256
- ```bash
257
- python cli.py interactive
258
- ```
259
-
260
- In this mode, you can choose among several actions such as login, logout, opening contests, checking demo cases, submitting solutions, and reconfiguring settings.
261
-
262
- ---
263
-
264
- ## Dependencies
265
-
266
- - **Selenium:** For browser automation and web interactions.
267
- - **webdriver-manager:** To handle ChromeDriver installation and updates.
268
- - **Click & InquirerPy:** For building the CLI and interactive prompts.
269
- - **Rich & Colorama:** For styled terminal outputs and color support.
270
- - **Pandas & Tabulate:** For generating and displaying submission verdict tables.
271
-
272
- Make sure you have the latest version of Google Chrome installed to ensure compatibility with ChromeDriver.
273
-
274
- ---
275
-
276
- ## Troubleshooting
277
-
278
- - **Chrome Profile in Use:**
279
- If you receive an error indicating that the Chrome profile is already being used, ensure that all Chrome windows are closed before starting ChefMate.
280
-
281
- - **Solution File Issues:**
282
- If ChefMate cannot locate your solution file, double-check the path in the configuration (or re-run the `setup` command).
283
-
284
- - **Configuration Errors:**
285
- If the configuration file is corrupted, ChefMate will automatically generate a new default configuration in `~/.chefmate/config.json`.
286
-
287
- - **Network/Slow Load Problems:**
288
- For slow networks, ChefMate includes retries during login and test case checks. If problems persist, try restarting your browser or re-running the command.
289
-
290
- ---
291
-
292
- ## Future Improvements
293
-
294
- - **Enhanced Error Reporting:**
295
- Additional debugging information for failures during submissions and test case validations.
296
- - **Multi-Language Support:**
297
- Extending support for more languages and custom code editor integration.
298
- - **GUI Implementation:**
299
- A graphical user interface for those who prefer not to use the CLI.
300
- - **Extended Contest Support:**
301
- Integration with more competitive programming sites.
302
-
303
- ---
304
-
305
- ## License
306
-
307
- ChefMate is open source software released under the [MIT License](LICENSE).
308
-
309
- ---
310
-
311
- ChefMate is designed with flexibility and practicality in mind to reduce the repetitive tasks of contest participation, leaving you free to concentrate on solving problems and improving your competitive programming skills.
312
-
313
- Happy Coding!
@@ -1,11 +0,0 @@
1
- chefmate/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
- chefmate/browser_manager.py,sha256=V1khfGVj8aeOmuQmVZLHs5H56vZRvtI97-nNe6pTK6E,2866
3
- chefmate/chefmate_core.py,sha256=F66-7gJJtn0_a6nM3HWLe58-3ExcAA82HK0ujmzrmEU,69631
4
- chefmate/cli.py,sha256=5GtohPcnSY8ygqLqZyMwZQioWfvMlF9KHTvYN15CB-4,9323
5
- chefmate/config.py,sha256=itkFruFKMX7eday8UnAYOfnVMthivn20tiTlG87czyA,2220
6
- chefmate-1.0.1.dist-info/licenses/LICENSE,sha256=gIUzdNdf-vbONssDRz-fj0uTywroTk9_ZBedvpj57XU,1094
7
- chefmate-1.0.1.dist-info/METADATA,sha256=eYb8gWDpR_rRRFXsLHgS41ObQ0eq2Cysv7VNo7Ch2rk,11858
8
- chefmate-1.0.1.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
9
- chefmate-1.0.1.dist-info/entry_points.txt,sha256=bu-w_FqHbrOtY-gTEe0WLVNWQZa8fOT2EPCMmSEpjfI,54
10
- chefmate-1.0.1.dist-info/top_level.txt,sha256=jOlvGtNNEYlsbwLBD2lpAmZBSo1wq2dydfAM1lP_Ago,9
11
- chefmate-1.0.1.dist-info/RECORD,,
@@ -1,2 +0,0 @@
1
- [console_scripts]
2
- chefmate = chefmate.cli:interactive