├── .gitattributes ├── README.md ├── assets ├── sample output files │ ├── out.epub │ └── out.html └── screenshots │ ├── driver path.PNG │ ├── epub_writer.PNG │ ├── main.PNG │ ├── sample_out_epub.PNG │ └── sample_out_html.PNG ├── chapters.pickle ├── driver ├── chromedriver └── chromedriver.exe ├── epub_writer.py ├── main.py ├── out.html ├── requirements.txt ├── track.conf └── utils.py /.gitattributes: -------------------------------------------------------------------------------- 1 | *.* linguist-language=Python 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Leetcode Questions Scraper 2 | 3 | > Note: If you want to download daily updated problems you can visit my repo [Leetcode Questions](https://github.com/Bishalsarang/Leetcode-Questions) which basically checks leetcode daily and dowloads new problems if available. Here is the preview link for latest html https://bishalsarang.github.io/Leetcode-Questions/out.html 4 | 5 | 6 | Leetcode Questions Scraper is a simple scrapper built on top of Selenium that fetches all the problems from leetcode and write as html and epub files. 7 | 8 | Although leetcode doesn't provide an official API to fetch all the list of problems, we can use the API url [https://leetcode.com/api/problems/algorithms/](https://leetcode.com/api/problems/algorithms/) used by leetcode internally to fetch problems that returns a json file containing info about problems. 9 | The json file looks like this
10 | ![enter image description here](https://qph.fs.quoracdn.net/main-qimg-4ddf7b592d1a47df4385ffc714c215b7)
11 | We can build links to each problem as 12 | 13 | “https://leetcode.com/problems/" + question_title_slug 14 | After getting the problem link we can fetch the content from the page using selenium (as Leetcode is built using react where content is rendered using JS we can't use lightweight library like requests). 15 | 16 | You can download the sample html and epub containing 11 problems [here](https://github.com/Bishalsarang/Leetcode-Questions-Scrapper/tree/master/assets/sample%20output%20files). 17 | 18 | ## Requirements 19 | 20 | I have tested it on windows machine running with Google Chrome 77.0.3865.75 and chrome driver from [here](https://chromedriver.storage.googleapis.com/index.html?path=77.0.3865.40/) and put it inside driver directory. 21 | I haven't tested with Linux and Mac but you can download chrome driver for respective platform and make change to `CHROMEDRIVER_PATH` inside `main.py` 22 | 23 | Pip install all the requirements. 24 | 25 | requests==2.22.0 26 | beautifulsoup4==4.8.0 27 | selenium==3.141.0 28 | EbookLib==0.17.1 29 | colorama==0.4.1 30 | 31 | 32 | ## How to use 33 | - Clone the repo and install all the dependencies including latest google chrome and latest chrome driver 34 | - Update chrome driver path 35 | - Run the following commands to download all algorithmic problems from leetcode 36 | `python main.py` 37 | ![enter image description here](https://raw.githubusercontent.com/Bishalsarang/Leetcode-Questions-Scrapper/master/assets/screenshots/main.PNG) 38 | This downloads problem contents to 2 files: *****out.html***** and ***chapters.pickle***. 39 | 40 | **NOTE:** Leetcode may temporarily block requests. If the error occurs, wait for sometime and try again or use the proxy. Don't worry, Since, the previous state is saved to ***track.conf*** file, the download resumes from where it failed. 41 | 42 | Here is how sample ***out.html*** looks like. 43 | ![Sample out.html](https://raw.githubusercontent.com/Bishalsarang/Leetcode-Questions-Scrapper/master/assets/screenshots/sample_out_html.PNG) 44 | 45 | After ***main.py*** script executes successfully. The pickle file is automatically converted to "***Leetcode Questions.epub***". 46 | 47 | But you can also convert manually to epub with existing downloaded content with. 48 | `python epub_writer.py` 49 | ![enter image description here](https://raw.githubusercontent.com/Bishalsarang/Leetcode-Questions-Scrapper/master/assets/screenshots/epub_writer.PNG) 50 | 51 | Here is how sample epub file looks like 52 | ![Sample](https://raw.githubusercontent.com/Bishalsarang/Leetcode-Questions-Scrapper/master/assets/screenshots/sample_out_epub.PNG) 53 | 54 | You can download sample files from here which contains 11 problem. 55 | 1. [Sample Out.epub](https://github.com/Bishalsarang/Leetcode-Questions-Scrapper/blob/master/assets/sample%20output%20files/out.epub) 56 | 2. [Sample Out.html](https://htmlpreview.github.io/?https://github.com/Bishalsarang/Leetcode-Questions-Scraper/blob/master/assets/sample%20output%20files/out.html) 57 | 58 | ## Support 59 | If you like this project and want to support it, consider buying me a coffee! 60 | 61 | [![Buy Me A Coffee](https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png)](https://www.buymeacoffee.com/bishalsarang) 62 | 63 | Thank you for your support! 64 | -------------------------------------------------------------------------------- /assets/sample output files/out.epub: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Bishalsarang/Leetcode-Questions-Scraper/c3d9b79572734b607b098b0adabc224a95b06530/assets/sample output files/out.epub -------------------------------------------------------------------------------- /assets/sample output files/out.html: -------------------------------------------------------------------------------- 1 | **********
1. Two Sum
2 | **********

Given an array of integers, return indices of the two numbers such that they add up to a specific target.

3 |

You may assume that each input would have exactly one solution, and you may not use the same element twice.

4 |

Example:

5 |
Given nums = [2, 7, 11, 15], target = 9,
  6 | 
  7 | Because nums[0] + nums[1] = 2 + 7 = 9,
  8 | return [0, 1].
  9 | 
10 |




******************
7. Reverse Integer
11 | ******************

Given a 32-bit signed integer, reverse digits of an integer.

12 |

Example 1:

13 |
Input: 123
 14 | Output: 321
 15 | 
16 |

Example 2:

17 |
Input: -123
 18 | Output: -321
 19 | 
20 |

Example 3:

21 |
Input: 120
 22 | Output: 21
 23 | 
24 |

Note:
25 | Assume we are dealing with an environment which could only store integers within the 32-bit signed integer range: [−231,  231 − 1]. For the purpose of this problem, assume that your function returns 0 when the reversed integer overflows.

26 |




********************
9. Palindrome Number
27 | ********************

Determine whether an integer is a palindrome. An integer is a palindrome when it reads the same backward as forward.

28 |

Example 1:

29 |
Input: 121
 30 | Output: true
 31 | 
32 |

Example 2:

33 |
Input: -121
 34 | Output: false
 35 | Explanation: From left to right, it reads -121. From right to left, it becomes 121-. Therefore it is not a palindrome.
 36 | 
37 |

Example 3:

38 |
Input: 10
 39 | Output: false
 40 | Explanation: Reads 01 from right to left. Therefore it is not a palindrome.
 41 | 
42 |

Follow up:

43 |

Coud you solve it without converting the integer to a string?

44 |




********************
13. Roman to Integer
45 | ********************

Roman numerals are represented by seven different symbols: I, V, X, L, C, D and M.

46 |
Symbol       Value
 47 | I             1
 48 | V             5
 49 | X             10
 50 | L             50
 51 | C             100
 52 | D             500
 53 | M             1000
54 |

For example, two is written as II in Roman numeral, just two one's added together. Twelve is written as, XII, which is simply X + II. The number twenty seven is written as XXVII, which is XX + V + II.

55 |

Roman numerals are usually written largest to smallest from left to right. However, the numeral for four is not IIII. Instead, the number four is written as IV. Because the one is before the five we subtract it making four. The same principle applies to the number nine, which is written as IX. There are six instances where subtraction is used:

56 | 61 |

Given a roman numeral, convert it to an integer. Input is guaranteed to be within the range from 1 to 3999.

62 |

Example 1:

63 |
Input: "III"
 64 | Output: 3
65 |

Example 2:

66 |
Input: "IV"
 67 | Output: 4
68 |

Example 3:

69 |
Input: "IX"
 70 | Output: 9
71 |

Example 4:

72 |
Input: "LVIII"
 73 | Output: 58
 74 | Explanation: L = 50, V= 5, III = 3.
 75 | 
76 |

Example 5:

77 |
Input: "MCMXCIV"
 78 | Output: 1994
 79 | Explanation: M = 1000, CM = 900, XC = 90 and IV = 4.
80 |




*************************
14. Longest Common Prefix
81 | *************************

Write a function to find the longest common prefix string amongst an array of strings.

82 |

If there is no common prefix, return an empty string "".

83 |

Example 1:

84 |
Input: ["flower","flow","flight"]
 85 | Output: "fl"
 86 | 
87 |

Example 2:

88 |
Input: ["dog","racecar","car"]
 89 | Output: ""
 90 | Explanation: There is no common prefix among the input strings.
 91 | 
92 |

Note:

93 |

All given inputs are in lowercase letters a-z.

94 |




*********************
20. Valid Parentheses
95 | *********************

Given a string containing just the characters '(', ')', '{', '}', '[' and ']', determine if the input string is valid.

96 |

An input string is valid if:

97 |
    98 |
  1. Open brackets must be closed by the same type of brackets.
  2. 99 |
  3. Open brackets must be closed in the correct order.
  4. 100 |
101 |

Note that an empty string is also considered valid.

102 |

Example 1:

103 |
Input: "()"
104 | Output: true
105 | 
106 |

Example 2:

107 |
Input: "()[]{}"
108 | Output: true
109 | 
110 |

Example 3:

111 |
Input: "(]"
112 | Output: false
113 | 
114 |

Example 4:

115 |
Input: "([)]"
116 | Output: false
117 | 
118 |

Example 5:

119 |
Input: "{[]}"
120 | Output: true
121 | 
122 |




**************************
21. Merge Two Sorted Lists
123 | **************************

Merge two sorted linked lists and return it as a new list. The new list should be made by splicing together the nodes of the first two lists.

124 |

Example: 125 |

Input: 1->2->4, 1->3->4
126 | Output: 1->1->2->3->4->4
127 | 
128 |





***************************************
26. Remove Duplicates from Sorted Array
129 | ***************************************

Given a sorted array nums, remove the duplicates in-place such that each element appear only once and return the new length.

130 |

Do not allocate extra space for another array, you must do this by modifying the input array in-place with O(1) extra memory.

131 |

Example 1:

132 |
Given nums = [1,1,2],
133 | 
134 | Your function should return length = 2, with the first two elements of nums being 1 and 2 respectively.
135 | 
136 | It doesn't matter what you leave beyond the returned length.
137 |

Example 2:

138 |
Given nums = [0,0,1,1,1,2,2,3,3,4],
139 | 
140 | Your function should return length = 5, with the first five elements of nums being modified to 0, 1, 2, 3, and 4 respectively.
141 | 
142 | It doesn't matter what values are set beyond the returned length.
143 | 
144 |

Clarification:

145 |

Confused why the returned value is an integer but your answer is an array?

146 |

Note that the input array is passed in by reference, which means modification to the input array will be known to the caller as well.

147 |

Internally you can think of this:

148 |
// nums is passed in by reference. (i.e., without making a copy)
149 | int len = removeDuplicates(nums);
150 | 
151 | // any modification to nums in your function would be known by the caller.
152 | // using the length returned by your function, it prints the first len elements.
153 | for (int i = 0; i < len; i++) {
154 |     print(nums[i]);
155 | }
156 |




******************
27. Remove Element
157 | ******************

Given an array nums and a value val, remove all instances of that value in-place and return the new length.

158 |

Do not allocate extra space for another array, you must do this by modifying the input array in-place with O(1) extra memory.

159 |

The order of elements can be changed. It doesn't matter what you leave beyond the new length.

160 |

Example 1:

161 |
Given nums = [3,2,2,3], val = 3,
162 | 
163 | Your function should return length = 2, with the first two elements of nums being 2.
164 | 
165 | It doesn't matter what you leave beyond the returned length.
166 | 
167 |

Example 2:

168 |
Given nums = [0,1,2,2,3,0,4,2], val = 2,
169 | 
170 | Your function should return length = 5, with the first five elements of nums containing 0, 1, 3, 0, and 4.
171 | 
172 | Note that the order of those five elements can be arbitrary.
173 | 
174 | It doesn't matter what values are set beyond the returned length.
175 |

Clarification:

176 |

Confused why the returned value is an integer but your answer is an array?

177 |

Note that the input array is passed in by reference, which means modification to the input array will be known to the caller as well.

178 |

Internally you can think of this:

179 |
// nums is passed in by reference. (i.e., without making a copy)
180 | int len = removeElement(nums, val);
181 | 
182 | // any modification to nums in your function would be known by the caller.
183 | // using the length returned by your function, it prints the first len elements.
184 | for (int i = 0; i < len; i++) {
185 |     print(nums[i]);
186 | }
187 |




**********************
28. Implement strStr()
188 | **********************

Implement strStr().

189 |

Return the index of the first occurrence of needle in haystack, or -1 if needle is not part of haystack.

190 |

Example 1:

191 |
Input: haystack = "hello", needle = "ll"
192 | Output: 2
193 | 
194 |

Example 2:

195 |
Input: haystack = "aaaaa", needle = "bba"
196 | Output: -1
197 | 
198 |

Clarification:

199 |

What should we return when needle is an empty string? This is a great question to ask during an interview.

200 |

For the purpose of this problem, we will return 0 when needle is an empty string. This is consistent to C's strstr() and Java's indexOf().

201 |




************************** -------------------------------------------------------------------------------- /assets/screenshots/driver path.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Bishalsarang/Leetcode-Questions-Scraper/c3d9b79572734b607b098b0adabc224a95b06530/assets/screenshots/driver path.PNG -------------------------------------------------------------------------------- /assets/screenshots/epub_writer.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Bishalsarang/Leetcode-Questions-Scraper/c3d9b79572734b607b098b0adabc224a95b06530/assets/screenshots/epub_writer.PNG -------------------------------------------------------------------------------- /assets/screenshots/main.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Bishalsarang/Leetcode-Questions-Scraper/c3d9b79572734b607b098b0adabc224a95b06530/assets/screenshots/main.PNG -------------------------------------------------------------------------------- /assets/screenshots/sample_out_epub.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Bishalsarang/Leetcode-Questions-Scraper/c3d9b79572734b607b098b0adabc224a95b06530/assets/screenshots/sample_out_epub.PNG -------------------------------------------------------------------------------- /assets/screenshots/sample_out_html.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Bishalsarang/Leetcode-Questions-Scraper/c3d9b79572734b607b098b0adabc224a95b06530/assets/screenshots/sample_out_html.PNG -------------------------------------------------------------------------------- /chapters.pickle: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Bishalsarang/Leetcode-Questions-Scraper/c3d9b79572734b607b098b0adabc224a95b06530/chapters.pickle -------------------------------------------------------------------------------- /driver/chromedriver: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Bishalsarang/Leetcode-Questions-Scraper/c3d9b79572734b607b098b0adabc224a95b06530/driver/chromedriver -------------------------------------------------------------------------------- /driver/chromedriver.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Bishalsarang/Leetcode-Questions-Scraper/c3d9b79572734b607b098b0adabc224a95b06530/driver/chromedriver.exe -------------------------------------------------------------------------------- /epub_writer.py: -------------------------------------------------------------------------------- 1 | from ebooklib import epub 2 | import colorama 3 | from colorama import Back, Fore 4 | import pickle 5 | 6 | colorama.init() 7 | 8 | def write(file_name, title, author, chapters): 9 | # Ebook 10 | book = epub.EpubBook() 11 | 12 | # set metadata 13 | book.set_identifier('id123456') 14 | book.set_title(title) 15 | book.set_language('en') 16 | book.add_author(author) 17 | book.add_author('Anonymous', file_as='Anonymous', role='ill', uid='coauthor') 18 | 19 | toc = [] 20 | spine = ['nav'] 21 | # For each chapter add chapter to the book, TOC and spine 22 | for chapter in chapters: 23 | book.add_item(chapter) 24 | toc.append(epub.Link(chapter.file_name, chapter.title, chapter.title)) 25 | spine.append(chapter) 26 | 27 | # define Table Of Contents 28 | book.toc = tuple(toc) 29 | 30 | # add default NCX and Nav file 31 | book.add_item(epub.EpubNcx()) 32 | book.add_item(epub.EpubNav()) 33 | 34 | # define CSS style 35 | style = 'pre{white-space:pre-wrap;background:#f7f9fa;padding:10px 15px;color:#263238;line-height:1.6;font-size:13px;border-radius:3px margin-top: 0;margin-bottom:1em;overflow:auto}b,strong{font-weight:bolder}#title{font-size:16px;color:#212121;font-weight:600;margin-bottom:10px}hr{height:10px;border:0;box-shadow:0 10px 10px -10px #8c8b8b inset}' 36 | nav_css = epub.EpubItem(uid="style_nav", file_name="style/nav.css", media_type="text/css", content=style) 37 | 38 | # add CSS file 39 | book.add_item(nav_css) 40 | 41 | # basic spine 42 | book.spine = spine 43 | 44 | # write to the file 45 | epub.write_epub(file_name, book, {}) 46 | 47 | print(Back.GREEN + Fore.BLACK + " File " + Back.YELLOW + f" {file_name} " + Back.GREEN + " Successfully Written ") 48 | def main(): 49 | # Load chapters list that stores chapter info 50 | # Store chapter info 51 | with open('chapters.pickle', 'rb') as f: 52 | chapters = pickle.load(f) 53 | 54 | 55 | write("Leetcode Questions.epub", "Leetcode Questions", "Anonymous", chapters) 56 | 57 | 58 | if __name__ == "__main__": 59 | main() -------------------------------------------------------------------------------- /main.py: -------------------------------------------------------------------------------- 1 | # Author: Bishal Sarang 2 | import json 3 | import pickle 4 | import time 5 | 6 | import bs4 7 | import colorama 8 | import requests 9 | from colorama import Back, Fore 10 | from ebooklib import epub 11 | from selenium import webdriver 12 | from selenium.webdriver.chrome.options import Options 13 | from selenium.webdriver.common.by import By 14 | from selenium.webdriver.support import expected_conditions as EC 15 | from selenium.webdriver.support.ui import WebDriverWait 16 | from utils import * 17 | import epub_writer 18 | 19 | # Initialize Colorama 20 | colorama.init(autoreset=True) 21 | 22 | # Setup Selenium Webdriver 23 | CHROMEDRIVER_PATH = r"./driver/chromedriver.exe" 24 | options = Options() 25 | options.headless = True 26 | # Disable Warning, Error and Info logs 27 | # Show only fatal errors 28 | options.add_argument("--log-level=3") 29 | driver = webdriver.Chrome(executable_path=CHROMEDRIVER_PATH, options=options) 30 | 31 | 32 | # Get upto which problem it is already scraped from track.conf file 33 | completed_upto = read_tracker("track.conf") 34 | 35 | # Load chapters list that stores chapter info 36 | # Store chapter info 37 | with open('chapters.pickle', 'rb') as f: 38 | chapters = pickle.load(f) 39 | 40 | def download(problem_num, url, title, solution_slug): 41 | print(Fore.BLACK + Back.CYAN + f"Fetching problem num " + Back.YELLOW + f" {problem_num} " + Back.CYAN + " with url " + Back.YELLOW + f" {url} ") 42 | n = len(title) 43 | 44 | try: 45 | 46 | driver.get(url) 47 | # Wait 30 secs or until div with class '_1l1MA' appears 48 | element = WebDriverWait(driver, 30).until( 49 | EC.visibility_of_element_located((By.CLASS_NAME, "_1l1MA")) 50 | ) 51 | # Get current tab page source 52 | html = driver.page_source 53 | soup = bs4.BeautifulSoup(html, "html.parser") 54 | 55 | # Construct HTML 56 | title_decorator = '*' * n 57 | problem_title_html = title_decorator + f'
{title}
' + '\n' + title_decorator 58 | problem_html = problem_title_html + str(soup.find("div", {"class": "_1l1MA"})) + '



' 59 | 60 | # Append Contents to a HTML file 61 | with open("out.html", "ab") as f: 62 | f.write(problem_html.encode(encoding="utf-8")) 63 | 64 | # create and append chapters to construct an epub 65 | c = epub.EpubHtml(title=title, file_name=f'chap_{problem_num}.xhtml', lang='hr') 66 | c.content = problem_html 67 | chapters.append(c) 68 | 69 | 70 | # Write List of chapters to pickle file 71 | dump_chapters_to_file(chapters) 72 | # Update upto which the problem is downloaded 73 | update_tracker('track.conf', problem_num) 74 | print(Fore.BLACK + Back.GREEN + f"Writing problem num " + Back.YELLOW + f" {problem_num} " + Back.GREEN + " with url " + Back.YELLOW + f" {url} " ) 75 | print(Fore.BLACK + Back.GREEN + " successfull ") 76 | # print(f"Writing problem num {problem_num} with url {url} successfull") 77 | 78 | except Exception as e: 79 | print(Back.RED + f" Failed Writing!! {e} ") 80 | driver.quit() 81 | 82 | def main(): 83 | 84 | # Leetcode API URL to get json of problems on algorithms categories 85 | ALGORITHMS_ENDPOINT_URL = "https://leetcode.com/api/problems/algorithms/" 86 | 87 | # Problem URL is of format ALGORITHMS_BASE_URL + question__title_slug 88 | # If question__title_slug = "two-sum" then URL is https://leetcode.com/problems/two-sum 89 | ALGORITHMS_BASE_URL = "https://leetcode.com/problems/" 90 | 91 | # Load JSON from API 92 | algorithms_problems_json = requests.get(ALGORITHMS_ENDPOINT_URL).content 93 | algorithms_problems_json = json.loads(algorithms_problems_json) 94 | 95 | styles_str = "" 96 | with open("out.html", "ab") as f: 97 | f.write(styles_str.encode(encoding="utf-8")) 98 | 99 | # List to store question_title_slug 100 | links = [] 101 | for child in algorithms_problems_json["stat_status_pairs"]: 102 | # Only process free problems 103 | if not child["paid_only"]: 104 | question__title_slug = child["stat"]["question__title_slug"] 105 | question__article__slug = child["stat"]["question__article__slug"] 106 | question__title = child["stat"]["question__title"] 107 | frontend_question_id = child["stat"]["frontend_question_id"] 108 | difficulty = child["difficulty"]["level"] 109 | links.append((question__title_slug, difficulty, frontend_question_id, question__title, question__article__slug)) 110 | 111 | # Sort by difficulty follwed by problem id in ascending order 112 | links = sorted(links, key=lambda x: (x[1], x[2])) 113 | 114 | try: 115 | for i in range(completed_upto + 1, len(links)): 116 | question__title_slug, _ , frontend_question_id, question__title, question__article__slug = links[i] 117 | url = ALGORITHMS_BASE_URL + question__title_slug 118 | title = f"{frontend_question_id}. {question__title}" 119 | 120 | # Download each file as html and write chapter to chapters.pickle 121 | download(i, url , title, question__article__slug) 122 | 123 | # Sleep for 20 secs for each problem and 2 minns after every 30 problems 124 | if i % 30 == 0: 125 | print(f"Sleeping 120 secs\n") 126 | time.sleep(120) 127 | else: 128 | print(f"Sleeping 20 secs\n") 129 | time.sleep(5) 130 | 131 | finally: 132 | # Close the browser after download 133 | driver.quit() 134 | 135 | try: 136 | epub_writer.write("Leetcode Questions.epub", "Leetcode Questions", "Anonymous", chapters) 137 | print(Back.GREEN + "All operations successful") 138 | except Exception as e: 139 | print(Back.RED + f"Error making epub {e}") 140 | 141 | 142 | 143 | if __name__ == "__main__": 144 | main() 145 | -------------------------------------------------------------------------------- /out.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Bishalsarang/Leetcode-Questions-Scraper/c3d9b79572734b607b098b0adabc224a95b06530/requirements.txt -------------------------------------------------------------------------------- /track.conf: -------------------------------------------------------------------------------- 1 | -1 -------------------------------------------------------------------------------- /utils.py: -------------------------------------------------------------------------------- 1 | """ 2 | Contains utility function to update upto which the problems has been downloaded, writing chapter info to a file, resetting configuration, 3 | reading upto which the problems has been downloaded 4 | """ 5 | import pickle 6 | 7 | def update_tracker(file_name, problem_num): 8 | """ 9 | 10 | """ 11 | with open(file_name, "w") as f: 12 | f.write(str(problem_num)) 13 | 14 | def dump_chapters_to_file(chapters): 15 | """ 16 | 17 | """ 18 | with open('chapters.pickle', 'wb') as f: 19 | pickle.dump(chapters, f) 20 | 21 | def reset_configuration(): 22 | """ 23 | Resets problem num downloaded upto to -1 24 | Resets all the chapters 25 | Resets html file 26 | """ 27 | update_tracker("track.conf", -1) 28 | dump_chapters_to_file([]) 29 | 30 | with open("out.html", "wb") as f: 31 | f.write(b" ") 32 | 33 | 34 | def read_tracker(file_name): 35 | """ 36 | 37 | """ 38 | with open(file_name, "r") as f: 39 | return int(f.readline()) 40 | 41 | 42 | 43 | 44 | --------------------------------------------------------------------------------