33import getpass
44import logging
55import os
6- from datetime import datetime
76from string import Template
87from typing import List , Dict
98
109from leetcode import LeetCode
1110from leetcode_rest import Submission
12- from utils import language_to_extension , remove_special_characters
1311
14- PROBLEM_INFO_TEMPLATE = Template ('''${questionId} - ${title}
12+ PROBLEM_CONTENT_TEMPLATE = Template ('''${questionId} - ${title}
1513${difficulty} - https://leetcode.com/problems/${titleSlug}/
1614
1715${content}
2018
2119def parse_args ():
2220 parser = argparse .ArgumentParser (description = 'Export LeetCode solutions' )
23- parser .add_argument ('--username' , type = str , required = False , help = 'LeetCode username' )
24- parser .add_argument ('--password' , type = str , required = False , help = 'LeetCode password' )
21+ parser .add_argument ('--username' , type = str , required = False , help = 'Set LeetCode username' )
22+ parser .add_argument ('--password' , type = str , required = False , help = 'Set LeetCode password' )
2523 parser .add_argument ('--folder' , type = str , required = False , help = 'Output folder' , default = 'out' )
26- parser .add_argument ('--cookies' , type = str , required = False , help = 'LeetCode cookies' )
24+ parser .add_argument ('--cookies' , type = str , required = False , help = 'Set LeetCode cookies' )
2725 parser .add_argument ('-v' , '--verbose' , dest = 'verbose' , action = 'store_true' , help = 'Enable verbose logging details' )
2826 parser .add_argument ('-vv' , '--extra-verbose' , dest = 'extra_verbose' , action = 'store_true' ,
2927 help = 'Enable more verbose logging details' )
28+ parser .add_argument ('--problem-filename' , type = str , default = '${questionId} - ${titleSlug}.txt' ,
29+ help = 'Problem description filename format' )
30+ parser .add_argument ('--submission-filename' , type = str ,
31+ default = '${date_formatted} - ${status_display} - runtime ${runtime} - memory ${memory}.${extension}' ,
32+ help = 'Submission filename format' )
3033 parser .set_defaults (verbose = False , extra_verbose = False )
3134
3235 return parser .parse_args ()
@@ -51,23 +54,40 @@ class App(object):
5154 ]
5255 )
5356
54- leetcode = LeetCode ()
57+ problem_template = Template (args .problem_filename )
58+ submission_template = Template (args .submission_filename )
5559
56- if not args .cookies :
57- username = args .username
58- password = args .password
59-
60- if not username :
60+ leetcode = LeetCode ()
61+ username = ''
62+ password = ''
63+ cookies = ''
64+
65+ # Login into leetcode
66+ if (not args .username or not args .password ) and not args .cookies :
67+ choice = input ("How do you want to login?\n 1 - Username and Password\n 2 - Cookies\n " )
68+ while choice != '1' and choice != '2' :
69+ print ("Choice not valid, input 1 or 2" )
70+ choice = input ("How do you want to login?\n 1 - Username and Password\n 2 - Cookies\n " )
71+
72+ if choice == '1' :
6173 username = input ("Insert LeetCode username: " )
62- if not password :
6374 password = getpass .getpass (prompt = "Insert LeetCode password: " )
64- if not leetcode .log_in (args .username , args .password ):
65- print (
66- "Login not successful! You might have entered the wrong username/password or you need to complete the reCAPTCHA. If you need to complete the captcha, log in with the cookies instead. Check the log for more informaton." )
67- exit (1 )
75+ else :
76+ cookies = input ("Insert LeetCode cookies: " )
6877 else :
69- leetcode .set_cookies (args .cookies )
78+ username = args .username
79+ password = args .password
80+ cookies = args .cookies
81+
82+ if username and password and not leetcode .log_in (args .username , args .password ):
83+ print (
84+ "Login not successful! You might have entered the wrong username/password or you need to complete the reCAPTCHA. If you need to complete the reCAPTCHA, log in with the cookies instead. Check the log for more information." )
85+ exit (1 )
86+
87+ if cookies :
88+ leetcode .set_cookies (cookies )
7089
90+ # Create output folder if it doesn't already exist
7191 if not os .path .exists (args .folder ):
7292 os .mkdir (args .folder )
7393 os .chdir (args .folder )
@@ -81,15 +101,15 @@ class App(object):
81101 else :
82102 logging .info (f"Folder { slug } already exists" )
83103 os .chdir (slug )
84- problem_info = leetcode .get_problem (slug )
85- info_filename = f" { problem_info . questionId } - { slug } .txt"
104+ problem_description = leetcode .get_problem (slug )
105+ info_filename = problem_template . substitute ( ** problem_description . __dict__ )
86106 if not os .path .exists (info_filename ):
87107 info_file = open (info_filename , 'w+' )
88- info_file .write (PROBLEM_INFO_TEMPLATE .substitute (** problem_info .__dict__ ))
108+ info_file .write (PROBLEM_CONTENT_TEMPLATE .substitute (** problem_description .__dict__ ))
89109 info_file .close ()
90110
91111 for sub in submissions [slug ]:
92- sub_filename = f" { datetime . fromtimestamp ( sub .timestamp ). strftime ( '%Y-%m-%d %H.%M.%S' ) } - { sub . status_display } - runtime { remove_special_characters ( sub . runtime ) } - memory { remove_special_characters ( sub . memory ) } . { language_to_extension ( sub . lang ) } "
112+ sub_filename = submission_template . substitute ( ** sub .__dict__ )
93113 if not os .path .exists (sub_filename ):
94114 logging .info (f"Writing { slug } /{ sub_filename } " )
95115 sub_file = open (sub_filename , 'w+' )
0 commit comments