├── LICENSE ├── README.md ├── VSP_ChapPage_PageDown.py ├── VSP_ChapPage_Standard.py ├── VitalSourcePrinter.py └── VitalSourcePrinter_PageDown.py /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016 LifeAlgorithm 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # VitalSourcePrinter 2 | Code to legally and automatically print your purchased e-books from VitalSource.com 3 | 4 | This program automates the printing of PDF's from the VitalSource Bookshelf. The VitalSource Bookshelf usually only lets the user print 2 pages at a time, and manually doing this for the entire book is tedious and time consuming. This program automatically prints any selection or the entirety of an e-book, page by page, and rapidly concatenates everything into a single PDF file. As this program makes use of keyboard automation, this process assumes that the user is away from the computer for the duration of the process, though the user at any time can stop the script from continuing. 5 | 6 | New scripts have been introduced for situations where the pages appear like "4-1" and situations where the user is required to press Ctrl + Pagedown to go to the next chapter. 7 | 8 | Legal disclaimer: 9 | Usage of any content produced by this script must abide the terms set out by VitalSource at https://support.vitalsource.com/hc/en-us/articles/204612518. In a nutshell this means no commercial usage or distribution, and only personal use is allowed. If you do decide to mass distribute, do so at your own risk since your name and email will appear on the top page of each print out. 10 | 11 | ## Getting Started 12 | 13 | Here's a link to the video tutorial (made for the original script): https://www.youtube.com/watch?v=6TUxpMezwUA 14 | 15 | To get started you are going to need a working version of Python 3 because as of this time the only working script is written in Python 3. Visit https://www.python.org/downloads/ to find the desired version for your operating system. 16 | 17 | If you're just installing Python 3 for the first time or reinstalling it, I highly recommend using Python 3.4.0 or higher as this version comes built with a feature called pip that easily allows you to install approved third party packages not included with Python by default. To find more information about pip, visit: https://pypi.python.org/pypi/pip. 18 | 19 | Note: If you're on Linux or Ubuntu, pip doesn't come with 3.4.0 or higher. The part of this section involving pip is referenced from https://automatetheboringstuff.com, a book that is a large inspiration for this program and one that I would highly recommend to anyone learning python. To learn how to get pip on Ubuntu or Linux, visit https://automatetheboringstuff.com/appendixa/ 20 | 21 | You're also going to need the VitalSource Bookshelf software, which you can find at: https://support.vitalsource.com/hc/en-us/articles/201344733-Bookshelf-Download-Page 22 | 23 | The next things you need are the following third party packages: 24 | - PyPDF2 25 | - pyautogui 26 | 27 | You of course must have Python 3 to install these packages. The easiest way to securely download and install these packages involves calling pip from your command prompt / terminal. If you don't have pip installed, you will have to manually download and insert these packages: 28 | https://docs.python.org/3/install/ 29 | 30 | This guide will proceed using pip. Navigate to your terminal and type the following commands one line at a time: 31 | 32 | 33 | Windows users 34 | 35 | ``` 36 | pip install --upgrade pip 37 | pip install PyPDF2 38 | pip install Pillow 39 | pip install pyautogui 40 | ``` 41 | OS X and Linux users: 42 | 43 | ``` 44 | pip3 install --upgrade pip 45 | pip3 install PyPDF2 46 | pip3 install Pillow 47 | pip3 install pyautogui 48 | ``` 49 | 50 | The first command is run as a precatuionary step to catch an error with Pillow not installing correctly and a missing dependency. If Pillow still doesn't install correctly, try ```easy_install Pillow ``` if you're on Windows and ```sudo easy_install Pillow``` if you're on Mac or Linux. 51 | 52 | Now you're ready to get started. In the case that you find the remainder of this tutorial visually hard to follow, be sure to check out the tutorial video. 53 | 54 | ## Walkthrough 55 | 56 | This section will go through each part of the process step-by-step. 57 | 58 | ### Pre-requisites 59 | 60 | Even with the necessary packages and software components, a few things need to be set before the script can function correctly. 61 | 62 | First open up VitalSource Book Shelf. Double click on the ebook you want to print to get it to pop-out. Now that you have it in place, make a new destination folder for your printed ebook to be located. A simple example could be a folder on your desktop called "Ebook". Make sure this folder doesn't contain a pdf named "Ebook.pdf," as that is used as a temp file name by the script. 63 | 64 | The next part is very important. The script will not work unless these three pre-conditions are met: 65 | 66 | - You need to have a PDF printer that doesn't automatically open the newly printed PDF 67 | - You need to print a "sample pdf" at the location of your destination ebook folder 68 | - You need sufficient disk space to save, as the output PDF tends to be large in size (possibly up to a GB or more) 69 | 70 | Firstly, you need to have a PDF printer that doesn't automatically open the newly printed PDF. For example, Adobe does this. You will need to disable this functionality if want the script to work. In the future, the script can be improved to account for this situation. One working PDF printer that comes with Windows is "Microsoft Print to PDF" and I reccommend using that if you are on Windows. I'm currently not too familiar with PDF printers for OS X and other systems and it would be appreciated if anyone can give an example of the analog for "Microsoft Print to PDF." Otherwise, any PDF printer that doesn't open new PDF's automatically, or one that can turn off this feature, will work. 71 | 72 | The second condition is that a "sample pdf" needs to be printed at the location of your ebook folder. This needs to be done to ensure that all intermediary PDF files being printed from VitalSource Bookshelf are in that ebook folder by default, as the script relies on this location. Ctrl + P and print a sample 2 page PDF to your ebook folder and that will set VitalSource to do its default printing there. 73 | 74 | The last condition is that you must have enough disk space to save your ebook. A 1270 page ebook took up 673 MB, which translates to about 1.89 MB per page. Bare in mind that ebooks widely differ in their content and hence there is a lot of variance in the possibilities of disk space usage so the final memory of the finished ebook could be widely different. To reduce the memory size of the finished ebook, various free PDF compressers exist such as https://smallpdf.com/compress-pdf, which has no file size limits and can reduce the size by up to 75% (the 1270 page ebook turned from 673 MB into 179 MB!). For safety, I reccommend having at least 1 GB of disk space available. 75 | 76 | ### Executing the script 77 | 78 | If you don't know what you are doing, open VitalSourcePrinter.py in an environment of your choice. Python usually comes with a default environment called IDLE that can be used if you don't have a custom environment that supports Python. This can be easily performed by right clicking the .py file and clicking "edit with IDLE." 79 | 80 | For viewing and operational purposes, it's a good idea to have the code view and the VitalSource ebook window close to each other. Once the script runs, it will automate keyboard actions so you need to be able to call focus to the VitalSource ebook window by clicking on it before the keyboard automations start. This will be touched upon soon. 81 | 82 | Now run the script. Follow the prompt and input the desired page ranges for roman numerals and regular numbers. If no roman numerals are desired, input "None" or "none". Only valid numbers and roman numerals work. If you're using another script aside from the original script, you will be prompted for other fields such as chapter count and chapter last page. 83 | 84 | Side note: Typing names like "inside front cover" won't be recieved by the script, and hence if you would like pages with specific names to be included, you would need to manually print those out and separately concatenate them to the finished Ebook pdf. This could be another feature to be added in the future. 85 | 86 | After the page ranges are entered, the program will prompt you to pick a folder. You must pick the ebook folder you printed your sample PDF in. After picking the folder, a countdown of 8 seconds will begin before the printing automation starts. Click on the active VitalSource window and the script will run. 87 | 88 | Note: To stop the script at any time, mouse over to the console window where the script is running and close it. It will say "the program is still running, do you want to kill it?" Choose "yes". 89 | 90 | Once the script runs to completion, you will see the message "done!" and the elapsed time in hours. 91 | 92 | ## Remarks 93 | 94 | A 1270 page ebook takes around 3.5 hours to print. That's about 6 pages a minute. Not too bad, though not perfect. The lengthy time is due to the design of the code, which was informed by trial and error. There were situations where names and keyboard operations would skip or not perform correctly due to happening too fast for VitalSource BookShelf to process. Moreover, intermediary files generated by VitalSource BookShelf were not recognized by the system if there was no waiting time after their generation, so waiting time was introduced to catch this error. At the end of the day (pun intended), you can use this script to print any ebook you want while sleeping, or when you are away from your computer of course. 95 | 96 | I hope this program is helpful and if any problems or issues arise, I encourage you to reach out to me and I will do my best to fix them. Any ideas, suggestions, or improvements would also be welcome. 97 | 98 | ~LifeAlgorithm 99 | -------------------------------------------------------------------------------- /VSP_ChapPage_PageDown.py: -------------------------------------------------------------------------------- 1 | ''' 2 | This script is designed to legally and automatically print your purchased e-books from VitalSource.com 3 | 4 | See ReadMe at https://github.com/LifeAlgorithm/VitalSourcePrinter and/or watch tutorial video for instructions 5 | 6 | This version is for printing chapter pages with the Ctrl + pagedown requirement 7 | ''' 8 | 9 | try: 10 | import PyPDF2 11 | import pyautogui 12 | import os 13 | import sys 14 | import time 15 | import warnings 16 | from tkinter import * 17 | import tkinter.filedialog as filedialog 18 | except: 19 | print("Please install PyPDF2 and pyautogui. Refer to video or documentation for help") 20 | sys.exit() 21 | 22 | 23 | def main(): 24 | 25 | start_time = time.time() 26 | warnings.filterwarnings("ignore") #Gets rid of harmless warnings on the console for excess whitespace 27 | 28 | 29 | print("Welcome to the VitalSource Ebook Printer!\nThis version is for chapter pages of the form 'Chapter-Page'\n") 30 | 31 | chapCount = int(input("Enter chapter count: ")) 32 | chapList = list(range(1, chapCount+1)) 33 | printList = list() 34 | for chapIndex in range(1, chapCount+1): 35 | chapPageList = int(input("Pages in chapter " + str(chapIndex) + ": ")) 36 | for chapPageIndex in range(1, chapPageList + 1): 37 | printList.append(str(chapIndex) + "-" + str(chapPageIndex)) 38 | 39 | 40 | #print (printList) 41 | 42 | root = Tk() 43 | root.withdraw() 44 | root.overrideredirect(True) 45 | root.geometry('0x0+0+0') 46 | root.deiconify() 47 | root.lift() 48 | root.focus_force() 49 | # credits to http://stackoverflow.com/questions/3375227/how-to-give-tkinter-file-dialog-focus 50 | 51 | filedir = filedialog.askdirectory() + '//' 52 | 53 | if len(printList)%2 != 0 : #ensures an even amount of print entries 54 | printList += [ printList[-1] ] 55 | 56 | tempHyIndex = printList[0].find("-") 57 | currentChapter = printList[0][0:tempHyIndex] #first chapter] 58 | 59 | print("\nClick on the active VitalSource window to get started.\nThe program will start in: 8") 60 | for seconds in range(8): 61 | time.sleep(1) 62 | if seconds == 7: 63 | print("Starting now...\n") 64 | break 65 | print(str(8 - (seconds + 1))) 66 | 67 | PageEntry1 = printList[0] 68 | PageEntry2 = printList[1] 69 | 70 | pyautogui.hotkey('ctrl', 'p') 71 | pyautogui.press(keys = 'tab', presses = 2, interval = 0.25) 72 | pyautogui.press('delete', 5) 73 | pyautogui.typewrite(PageEntry1) 74 | pyautogui.press('tab') 75 | pyautogui.press('delete', 5) 76 | pyautogui.typewrite(PageEntry2) 77 | pyautogui.typewrite(['tab', 'tab', 'enter', 'enter'], interval = 0.25 ) 78 | pyautogui.typewrite("Ebook", interval = 0.50) 79 | pyautogui.press('enter', interval = 0.5) 80 | time.sleep(0.25) 81 | 82 | 83 | for page in range(2, len(printList), 2): 84 | 85 | tempHyIndex = printList[page].find("-") 86 | tempChapter = printList[page][0:tempHyIndex] 87 | if currentChapter != tempChapter: 88 | currentChapter = tempChapter 89 | pyautogui.hotkey('ctrl', 'pagedown', interval = 0.25) 90 | 91 | pyautogui.hotkey('ctrl', 'p', interval = 0.25) 92 | pyautogui.press('tab', 2, interval = 0.25) 93 | pyautogui.press('delete', 5, interval = 0.25) 94 | pyautogui.typewrite(printList[page], interval = 0.25) 95 | pyautogui.press('tab', interval = 0.25) 96 | pyautogui.press('delete', 5, interval = 0.25) 97 | pyautogui.typewrite(printList[page + 1]) 98 | pyautogui.typewrite(['tab', 'tab', 'enter', 'enter'], interval = 0.75) 99 | pyautogui.typewrite("File2", interval = 0.5) 100 | pyautogui.press('enter', interval = 0.5) 101 | time.sleep(5) 102 | while (os.path.isfile(filedir + "Ebook.pdf") != True): 103 | time.sleep(2) 104 | while (os.path.isfile(filedir + "File2.pdf") != True): 105 | time.sleep(2) 106 | try: 107 | pdf1File = open(filedir + 'Ebook.pdf', 'rb') 108 | pdf2File = open(filedir + 'File2.pdf', 'rb') 109 | except: 110 | while (os.path.isfile(filedir + Ebook.pdf) != True): 111 | time.sleep(10) 112 | while (os.path.isfile(filedir + File2.pdf) != True): 113 | time.sleep(10) 114 | try: 115 | pdf1Reader = PyPDF2.PdfFileReader(pdf1File) 116 | except: 117 | time.sleep(5) 118 | pdf1Reader = PyPDF2.PdfFileReader(pdf1File) 119 | 120 | try: 121 | pdf2Reader = PyPDF2.PdfFileReader(pdf2File) 122 | except: 123 | time.sleep(5) 124 | pdf2Reader = PyPDF2.PdfFileReader(pdf2File) 125 | 126 | pdfWriter = PyPDF2.PdfFileWriter() 127 | for pageNum in range(pdf1Reader.numPages): 128 | pageObj = pdf1Reader.getPage(pageNum) 129 | pdfWriter.addPage(pageObj) 130 | for pageNum in range(pdf2Reader.numPages): 131 | pageObj = pdf2Reader.getPage(pageNum) 132 | pdfWriter.addPage(pageObj) 133 | pdfOutputFile = open(filedir + 'Ebook1.pdf', 'wb') 134 | pdfWriter.write(pdfOutputFile) 135 | pdfOutputFile.close() 136 | pdf1File.close() 137 | pdf2File.close() 138 | try: 139 | os.remove(filedir + 'Ebook.pdf') 140 | except: 141 | time.sleep(10) 142 | os.remove(filedir + 'Ebook.pdf') 143 | 144 | try: 145 | os.remove(filedir + 'File2.pdf') 146 | except: 147 | time.sleep(10) 148 | os.remove(filedir + 'File2.pdf') 149 | 150 | try: 151 | os.rename(filedir + 'Ebook1.pdf', filedir + 'Ebook.pdf') 152 | except: 153 | time.sleep(10) 154 | os.rename(filedir + 'Ebook1.pdf', filedir + 'Ebook.pdf') 155 | 156 | print("Page: " + str(page + 2) + ' of ' + str(len(printList) )) 157 | 158 | 159 | 160 | elapsed_time = time.time() - start_time 161 | print("\nDone!") 162 | print("This took " + "%.2f" % (elapsed_time/3600) + " hours.") 163 | 164 | if __name__ == "__main__": main() 165 | 166 | -------------------------------------------------------------------------------- /VSP_ChapPage_Standard.py: -------------------------------------------------------------------------------- 1 | ''' 2 | This script is designed to legally and automatically print your purchased e-books from VitalSource.com 3 | 4 | See ReadMe at https://github.com/LifeAlgorithm/VitalSourcePrinter and/or watch tutorial video for instructions 5 | 6 | This version is for printing chapter pages without the Ctrl + pagedown requirement 7 | ''' 8 | 9 | try: 10 | import PyPDF2 11 | import pyautogui 12 | import os 13 | import sys 14 | import time 15 | import warnings 16 | from tkinter import * 17 | import tkinter.filedialog as filedialog 18 | except: 19 | print("Please install PyPDF2 and pyautogui. Refer to video or documentation for help") 20 | sys.exit() 21 | 22 | 23 | def main(): 24 | 25 | start_time = time.time() 26 | warnings.filterwarnings("ignore") #Gets rid of harmless warnings on the console for excess whitespace 27 | 28 | 29 | print("Welcome to the VitalSource Ebook Printer!\nThis version is for chapter pages of the form 'Chapter-Page'\n") 30 | 31 | chapCount = int(input("Enter chapter count: ")) 32 | chapList = list(range(1, chapCount+1)) 33 | printList = list() 34 | for chapIndex in range(1, chapCount+1): 35 | chapPageList = int(input("Pages in chapter " + str(chapIndex) + ": ")) 36 | for chapPageIndex in range(1, chapPageList + 1): 37 | printList.append(str(chapIndex) + "-" + str(chapPageIndex)) 38 | 39 | 40 | #print (printList) 41 | 42 | root = Tk() 43 | root.withdraw() 44 | root.overrideredirect(True) 45 | root.geometry('0x0+0+0') 46 | root.deiconify() 47 | root.lift() 48 | root.focus_force() 49 | # credits to http://stackoverflow.com/questions/3375227/how-to-give-tkinter-file-dialog-focus 50 | 51 | filedir = filedialog.askdirectory() + '//' 52 | 53 | if len(printList)%2 != 0 : #ensures an even amount of print entries 54 | printList += [ printList[-1] ] 55 | 56 | 57 | print("\nClick on the active VitalSource window to get started.\nThe program will start in: 8") 58 | for seconds in range(8): 59 | time.sleep(1) 60 | if seconds == 7: 61 | print("Starting now...\n") 62 | break 63 | print(str(8 - (seconds + 1))) 64 | 65 | 66 | PageEntry1 = printList[0] 67 | PageEntry2 = printList[1] 68 | 69 | pyautogui.hotkey('ctrl', 'p') 70 | pyautogui.press(keys = 'tab', presses = 2, interval = 0.25) 71 | pyautogui.press('delete', 5) 72 | pyautogui.typewrite(PageEntry1) 73 | pyautogui.press('tab') 74 | pyautogui.press('delete', 5) 75 | pyautogui.typewrite(PageEntry2) 76 | pyautogui.typewrite(['tab', 'tab', 'enter', 'enter'], interval = 0.25 ) 77 | pyautogui.typewrite("Ebook", interval = 0.50) 78 | pyautogui.press('enter', interval = 0.5) 79 | time.sleep(0.25) 80 | 81 | 82 | for page in range(2, len(printList), 2): 83 | pyautogui.hotkey('ctrl', 'p', interval = 0.25) 84 | pyautogui.press('tab', 2, interval = 0.25) 85 | pyautogui.press('delete', 5, interval = 0.25) 86 | pyautogui.typewrite(printList[page], interval = 0.25) 87 | pyautogui.press('tab', interval = 0.25) 88 | pyautogui.press('delete', 5, interval = 0.25) 89 | pyautogui.typewrite(printList[page + 1]) 90 | pyautogui.typewrite(['tab', 'tab', 'enter', 'enter'], interval = 0.75) 91 | pyautogui.typewrite("File2", interval = 0.5) 92 | pyautogui.press('enter', interval = 0.5) 93 | time.sleep(5) 94 | while (os.path.isfile(filedir + "Ebook.pdf") != True): 95 | time.sleep(2) 96 | while (os.path.isfile(filedir + "File2.pdf") != True): 97 | time.sleep(2) 98 | try: 99 | pdf1File = open(filedir + 'Ebook.pdf', 'rb') 100 | pdf2File = open(filedir + 'File2.pdf', 'rb') 101 | except: 102 | while (os.path.isfile(filedir + Ebook.pdf) != True): 103 | time.sleep(10) 104 | while (os.path.isfile(filedir + File2.pdf) != True): 105 | time.sleep(10) 106 | try: 107 | pdf1Reader = PyPDF2.PdfFileReader(pdf1File) 108 | except: 109 | time.sleep(5) 110 | pdf1Reader = PyPDF2.PdfFileReader(pdf1File) 111 | 112 | try: 113 | pdf2Reader = PyPDF2.PdfFileReader(pdf2File) 114 | except: 115 | time.sleep(5) 116 | pdf2Reader = PyPDF2.PdfFileReader(pdf2File) 117 | 118 | pdfWriter = PyPDF2.PdfFileWriter() 119 | for pageNum in range(pdf1Reader.numPages): 120 | pageObj = pdf1Reader.getPage(pageNum) 121 | pdfWriter.addPage(pageObj) 122 | for pageNum in range(pdf2Reader.numPages): 123 | pageObj = pdf2Reader.getPage(pageNum) 124 | pdfWriter.addPage(pageObj) 125 | pdfOutputFile = open(filedir + 'Ebook1.pdf', 'wb') 126 | pdfWriter.write(pdfOutputFile) 127 | pdfOutputFile.close() 128 | pdf1File.close() 129 | pdf2File.close() 130 | try: 131 | os.remove(filedir + 'Ebook.pdf') 132 | except: 133 | time.sleep(10) 134 | os.remove(filedir + 'Ebook.pdf') 135 | 136 | try: 137 | os.remove(filedir + 'File2.pdf') 138 | except: 139 | time.sleep(10) 140 | os.remove(filedir + 'File2.pdf') 141 | 142 | try: 143 | os.rename(filedir + 'Ebook1.pdf', filedir + 'Ebook.pdf') 144 | except: 145 | time.sleep(10) 146 | os.rename(filedir + 'Ebook1.pdf', filedir + 'Ebook.pdf') 147 | 148 | print("Page: " + str(page + 2) + ' of ' + str(len(printList) )) 149 | 150 | 151 | 152 | elapsed_time = time.time() - start_time 153 | print("\nDone!") 154 | print("This took " + "%.2f" % (elapsed_time/3600) + " hours.") 155 | 156 | if __name__ == "__main__": main() 157 | 158 | 159 | -------------------------------------------------------------------------------- /VitalSourcePrinter.py: -------------------------------------------------------------------------------- 1 | 2 | ''' 3 | This script is designed to legally and automatically print your purchased e-books from VitalSource.com 4 | 5 | See ReadMe at https://github.com/LifeAlgorithm/VitalSourcePrinter and/or watch tutorial video for instructions 6 | ''' 7 | 8 | try: 9 | import PyPDF2 10 | import pyautogui 11 | import os 12 | import sys 13 | import time 14 | import warnings 15 | from tkinter import * 16 | import tkinter.filedialog as filedialog 17 | except: 18 | print("Please install PyPDF2 and pyautogui. Refer to video or documentation for help") 19 | sys.exit() 20 | 21 | def main(): 22 | 23 | start_time = time.time() 24 | warnings.filterwarnings("ignore") #Gets rid of harmless warnings on the console for excess whitespace 25 | 26 | numeral_map = tuple(zip((1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1), 27 | ('M', 'CM', 'D', 'CD', 'C', 'XC', 'L', 'XL', 'X', 'IX', 'V', 'IV', 'I') )) 28 | 29 | def int_to_roman(i): 30 | result = [] 31 | for integer, numeral in numeral_map: 32 | count = i // integer 33 | result.append(numeral * count) 34 | i -= integer * count 35 | return ''.join(result) 36 | 37 | def roman_to_int(n): 38 | i = result = 0 39 | for integer, numeral in numeral_map: 40 | while n[i:i + len(numeral)] == numeral: 41 | result += integer 42 | i += len(numeral) 43 | return result 44 | 45 | #Source of roman numeral coverters = http://code.activestate.com/recipes/81611-roman-numerals/ 46 | 47 | print("Welcome to the VitalSource Ebook Printer. \n") 48 | 49 | while(True): 50 | try: 51 | RomanStart = input("Roman Numeral Start (or 'No'): ") 52 | if RomanStart == 'No' or RomanStart == 'no': 53 | print("") 54 | break 55 | elif roman_to_int(RomanStart.upper()): 56 | RomanEnd = input("Roman Numeral End (If one page enter same page as first): ").upper() 57 | if (roman_to_int(RomanStart.upper())) > (roman_to_int(RomanEnd.upper())): 58 | print("\nFirst page must be less than last page.\n") 59 | continue 60 | print("First roman numeral is ", int_to_roman(roman_to_int(RomanStart.upper())), " second is ", int_to_roman(roman_to_int(RomanEnd.upper()))) 61 | proceed = input("Proceed? (Y/N): ") 62 | if proceed == 'Y' or proceed == 'y': 63 | print("") 64 | break 65 | else: 66 | continue 67 | else: 68 | print("Please enter valid roman numerals. Type 'No' to skip roman numerals.\n") 69 | except: 70 | print("Please a valid roman numeral. Type 'No' to skip roman numerals.\n") 71 | 72 | if not (RomanStart == 'No' or RomanStart == 'no'): 73 | RomanList = [] 74 | a = roman_to_int(RomanStart.upper()) 75 | b = roman_to_int(RomanEnd.upper()) 76 | 77 | for i in range(a,(b+1)): 78 | RomanList += [int_to_roman(i)] 79 | RomanBookList = [x.lower() for x in RomanList] 80 | 81 | while(True): 82 | try: 83 | NumberStart = int(input("First page: ")) 84 | NumberEnd = int(input("Last page: ")) 85 | if (type(NumberStart) != int) or (type(NumberStart) != int): 86 | print("Please enter valid numbers.\n") 87 | continue 88 | elif (NumberStart > NumberEnd): 89 | print("First page must be less than last page.\n") 90 | continue 91 | else: 92 | break 93 | except: 94 | print("Please enter valid page numbers.\n") 95 | 96 | NumberList = [] 97 | for i in range(int(NumberStart), int(NumberEnd)+1): 98 | NumberList += [ str(i) ] 99 | 100 | root = Tk() 101 | root.withdraw() 102 | root.overrideredirect(True) 103 | root.geometry('0x0+0+0') 104 | root.deiconify() 105 | root.lift() 106 | root.focus_force() 107 | # credits to http://stackoverflow.com/questions/3375227/how-to-give-tkinter-file-dialog-focus 108 | 109 | filedir = filedialog.askdirectory() + '//' 110 | 111 | if len(NumberList)%2 != 0 : 112 | NumberList += [ NumberList[-1] ] 113 | 114 | if not (RomanStart == 'No' or RomanStart == 'no'): 115 | if roman_to_int(RomanEnd.upper()): 116 | if len(RomanBookList)%2 != 0 : #ugly coding, but it gets the job done 117 | RomanBookList += [ RomanBookList[-1] ] 118 | 119 | print("\nClick on the active VitalSource window to get started.\nThe program will start in: 8") 120 | for seconds in range(8): 121 | time.sleep(1) 122 | if seconds == 7: 123 | print("Starting now...\n") 124 | break 125 | print(str(8 - (seconds + 1))) 126 | 127 | if not (RomanStart == 'No' or RomanStart == 'no'): 128 | 129 | PageEntry1 = RomanBookList[0] 130 | PageEntry2 = RomanBookList[1] 131 | 132 | pyautogui.hotkey('ctrl', 'p') 133 | pyautogui.press(keys = 'tab', presses = 2, interval = 0.25) 134 | pyautogui.press('delete', 5) 135 | pyautogui.typewrite(PageEntry1) 136 | pyautogui.press('tab') 137 | pyautogui.press('delete', 5) 138 | pyautogui.typewrite(PageEntry2) 139 | pyautogui.typewrite(['tab', 'tab', 'enter', 'enter'], interval = 0.25 ) 140 | pyautogui.typewrite("Ebook", interval = 0.50) 141 | pyautogui.press('enter', interval = 0.5) 142 | time.sleep(0.25) 143 | 144 | print("Page: " + '1' + ' of ' + str(len(RomanBookList) )) 145 | for page in range(2, len(RomanBookList), 2): 146 | pyautogui.hotkey('ctrl', 'p', interval = 0.25) 147 | pyautogui.press('tab', 2, interval = 0.25) 148 | pyautogui.press('delete', 6, interval = 0.25) 149 | pyautogui.typewrite(RomanBookList[page], interval = 0.25) 150 | pyautogui.press('tab', interval = 0.25) 151 | pyautogui.press('delete', 6, interval = 0.25) 152 | pyautogui.typewrite(RomanBookList[page + 1]) 153 | pyautogui.typewrite(['tab', 'tab', 'enter', 'enter'], interval = 0.75) 154 | pyautogui.typewrite("File2", interval = 0.5) 155 | pyautogui.press('enter', interval = 0.5) 156 | while (os.path.isfile(filedir + "Ebook.pdf") != True): 157 | time.sleep(2) 158 | while (os.path.isfile(filedir + "File2.pdf") != True): 159 | time.sleep(2) 160 | try: 161 | pdf1File = open(filedir + 'Ebook.pdf', 'rb') 162 | pdf2File = open(filedir + 'File2.pdf', 'rb') 163 | except: 164 | while (os.path.isfile(filedir + Ebook.pdf) != True): 165 | time.sleep(10) 166 | while (os.path.isfile(filedir + File2.pdf) != True): 167 | time.sleep(10) 168 | 169 | try: #not ideal handling , but it works. A bug that yields OSError(22, 'Invalid argument') should be investigated 170 | pdf1Reader = PyPDF2.PdfFileReader(pdf1File) 171 | except: 172 | time.sleep(5) 173 | pdf1Reader = PyPDF2.PdfFileReader(pdf1File) 174 | 175 | try: 176 | pdf2Reader = PyPDF2.PdfFileReader(pdf2File) 177 | except: 178 | time.sleep(5) 179 | pdf2Reader = PyPDF2.PdfFileReader(pdf2File) 180 | 181 | 182 | pdfWriter = PyPDF2.PdfFileWriter() 183 | for pageNum in range(pdf1Reader.numPages): 184 | pageObj = pdf1Reader.getPage(pageNum) 185 | pdfWriter.addPage(pageObj) 186 | for pageNum in range(pdf2Reader.numPages): 187 | pageObj = pdf2Reader.getPage(pageNum) 188 | pdfWriter.addPage(pageObj) 189 | pdfOutputFile = open(filedir + 'Ebook1.pdf', 'wb') 190 | pdfWriter.write(pdfOutputFile) 191 | pdfOutputFile.close() 192 | pdf1File.close() 193 | pdf2File.close() 194 | os.remove(filedir + 'Ebook.pdf') 195 | os.remove(filedir + 'File2.pdf') 196 | os.rename(filedir + 'Ebook1.pdf', filedir + 'Ebook.pdf') 197 | print("Page: " + str(page + 2) + ' of ' + str(len(RomanBookList))) 198 | print("\nRoman Numerals Done\n") 199 | 200 | else: 201 | PageEntry1 = NumberList[0] 202 | PageEntry2 = NumberList[1] 203 | 204 | pyautogui.hotkey('ctrl', 'p') 205 | pyautogui.press(keys = 'tab', presses = 2, interval = 0.25) 206 | pyautogui.press('delete', 5) 207 | pyautogui.typewrite(PageEntry1) 208 | pyautogui.press('tab') 209 | pyautogui.press('delete', 5) 210 | pyautogui.typewrite(PageEntry2) 211 | pyautogui.typewrite(['tab', 'tab', 'enter', 'enter'], interval = 0.25 ) 212 | pyautogui.typewrite("Ebook", interval = 0.50) 213 | pyautogui.press('enter', interval = 0.5) 214 | time.sleep(0.25) 215 | 216 | def NumberProcess(start): 217 | for page in range(start, len(NumberList), 2): 218 | pyautogui.hotkey('ctrl', 'p', interval = 0.25) 219 | pyautogui.press('tab', 2, interval = 0.25) 220 | pyautogui.press('delete', 5, interval = 0.25) 221 | pyautogui.typewrite(NumberList[page], interval = 0.25) 222 | pyautogui.press('tab', interval = 0.25) 223 | pyautogui.press('delete', 5, interval = 0.25) 224 | pyautogui.typewrite(NumberList[page + 1]) 225 | pyautogui.typewrite(['tab', 'tab', 'enter', 'enter'], interval = 0.75) 226 | pyautogui.typewrite("File2", interval = 0.5) 227 | pyautogui.press('enter', interval = 0.5) 228 | time.sleep(5) 229 | while (os.path.isfile(filedir + "Ebook.pdf") != True): 230 | time.sleep(2) 231 | while (os.path.isfile(filedir + "File2.pdf") != True): 232 | time.sleep(2) 233 | try: 234 | pdf1File = open(filedir + 'Ebook.pdf', 'rb') 235 | pdf2File = open(filedir + 'File2.pdf', 'rb') 236 | except: 237 | while (os.path.isfile(filedir + Ebook.pdf) != True): 238 | time.sleep(10) 239 | while (os.path.isfile(filedir + File2.pdf) != True): 240 | time.sleep(10) 241 | try: 242 | pdf1Reader = PyPDF2.PdfFileReader(pdf1File) 243 | except: 244 | time.sleep(5) 245 | pdf1Reader = PyPDF2.PdfFileReader(pdf1File) 246 | 247 | try: 248 | pdf2Reader = PyPDF2.PdfFileReader(pdf2File) 249 | except: 250 | time.sleep(5) 251 | pdf2Reader = PyPDF2.PdfFileReader(pdf2File) 252 | 253 | pdfWriter = PyPDF2.PdfFileWriter() 254 | for pageNum in range(pdf1Reader.numPages): 255 | pageObj = pdf1Reader.getPage(pageNum) 256 | pdfWriter.addPage(pageObj) 257 | for pageNum in range(pdf2Reader.numPages): 258 | pageObj = pdf2Reader.getPage(pageNum) 259 | pdfWriter.addPage(pageObj) 260 | pdfOutputFile = open(filedir + 'Ebook1.pdf', 'wb') 261 | pdfWriter.write(pdfOutputFile) 262 | pdfOutputFile.close() 263 | pdf1File.close() 264 | pdf2File.close() 265 | try: 266 | os.remove(filedir + 'Ebook.pdf') 267 | except: 268 | time.sleep(10) 269 | os.remove(filedir + 'Ebook.pdf') 270 | 271 | try: 272 | os.remove(filedir + 'File2.pdf') 273 | except: 274 | time.sleep(10) 275 | os.remove(filedir + 'File2.pdf') 276 | 277 | try: 278 | os.rename(filedir + 'Ebook1.pdf', filedir + 'Ebook.pdf') 279 | except: 280 | time.sleep(10) 281 | os.rename(filedir + 'Ebook1.pdf', filedir + 'Ebook.pdf') 282 | 283 | print("Page: " + str(page + 2) + ' of ' + str(len(NumberList) )) 284 | 285 | if not (RomanStart == 'No' or RomanStart == 'no'): 286 | NumberProcess(0) 287 | else: 288 | NumberProcess(2) 289 | 290 | elapsed_time = time.time() - start_time 291 | print("\nDone!") 292 | print("This took " + "%.2f" % (elapsed_time/3600) + " hours.") 293 | 294 | if __name__ == "__main__": main() 295 | 296 | 297 | ''' 298 | Final note 299 | 300 | I hope this script serves you well. A lot of the actual code was written for basic functionality and not neccessarily optimization 301 | and readability. Suggestions for refactoring and improvement are always appreciated. 302 | 303 | ''' 304 | -------------------------------------------------------------------------------- /VitalSourcePrinter_PageDown.py: -------------------------------------------------------------------------------- 1 | ''' 2 | This script is designed to legally and automatically print your purchased e-books from VitalSource.com 3 | 4 | See ReadMe at https://github.com/LifeAlgorithm/VitalSourcePrinter and/or watch tutorial video for instructions 5 | 6 | This version is for printing pages with the Ctrl + pagedown requirement 7 | ''' 8 | 9 | try: 10 | import PyPDF2 11 | import pyautogui 12 | import os 13 | import sys 14 | import time 15 | import warnings 16 | from tkinter import * 17 | import tkinter.filedialog as filedialog 18 | except: 19 | print("Please install PyPDF2 and pyautogui. Refer to video or documentation for help") 20 | sys.exit() 21 | 22 | def main(): 23 | 24 | start_time = time.time() 25 | warnings.filterwarnings("ignore") #Gets rid of harmless warnings on the console for excess whitespace 26 | 27 | numeral_map = tuple(zip((1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1), 28 | ('M', 'CM', 'D', 'CD', 'C', 'XC', 'L', 'XL', 'X', 'IX', 'V', 'IV', 'I') )) 29 | 30 | def int_to_roman(i): 31 | result = [] 32 | for integer, numeral in numeral_map: 33 | count = i // integer 34 | result.append(numeral * count) 35 | i -= integer * count 36 | return ''.join(result) 37 | 38 | def roman_to_int(n): 39 | i = result = 0 40 | for integer, numeral in numeral_map: 41 | while n[i:i + len(numeral)] == numeral: 42 | result += integer 43 | i += len(numeral) 44 | return result 45 | 46 | print("Welcome to the VitalSource Ebook Printer!\nThis version handles the page-down requirement for standard pages") 47 | 48 | while(True): 49 | try: 50 | RomanStart = input("Roman Numeral Start (or 'No'): ") 51 | if RomanStart == 'No' or RomanStart == 'no': 52 | print("") 53 | break 54 | elif roman_to_int(RomanStart.upper()): 55 | RomanEnd = input("Roman Numeral End (If one page enter same page as first): ").upper() 56 | if (roman_to_int(RomanStart.upper())) > (roman_to_int(RomanEnd.upper())): 57 | print("\nFirst page must be less than last page.\n") 58 | continue 59 | print("First roman numeral is ", int_to_roman(roman_to_int(RomanStart.upper())), " second is ", int_to_roman(roman_to_int(RomanEnd.upper()))) 60 | proceed = input("Proceed? (Y/N): ") 61 | if proceed == 'Y' or proceed == 'y': 62 | print("") 63 | break 64 | else: 65 | continue 66 | else: 67 | print("Please enter valid roman numerals. Type 'No' to skip roman numerals.\n") 68 | except: 69 | print("Please a valid roman numeral. Type 'No' to skip roman numerals.\n") 70 | 71 | if not (RomanStart == 'No' or RomanStart == 'no'): #if user typed in roman numerals 72 | RomanList = [] 73 | a = roman_to_int(RomanStart.upper()) 74 | b = roman_to_int(RomanEnd.upper()) 75 | 76 | for i in range(a,(b+1)): 77 | RomanList += [int_to_roman(i)] 78 | RomanBookList = [x.lower() for x in RomanList] 79 | 80 | while(True): 81 | try: 82 | NumberStart = int(input("First page: ")) 83 | NumberEnd = int(input("Last page: ")) 84 | if (type(NumberStart) != int) or (type(NumberStart) != int): 85 | print("Please enter valid numbers.\n") 86 | continue 87 | elif (NumberStart > NumberEnd): 88 | print("First page must be less than last page.\n") 89 | continue 90 | else: 91 | break 92 | except: 93 | print("Please enter valid page numbers.\n") 94 | 95 | NumberList = [] 96 | for i in range(int(NumberStart), int(NumberEnd)+1): 97 | NumberList += [ str(i) ] 98 | 99 | 100 | chapCount = int(input("Enter chapter count: ")) 101 | chapPageList = list(range(1, chapCount+1)) 102 | chapLastPageList = list() #will hold the last page of each chapter 103 | for chapIndex in range(1, chapCount+1): 104 | chapLastPageList.append(int(input("Last page in chapter " + str(chapIndex) + ": "))) 105 | 106 | 107 | print("Last page list: ", chapLastPageList) 108 | 109 | root = Tk() 110 | root.withdraw() 111 | root.overrideredirect(True) 112 | root.geometry('0x0+0+0') 113 | root.deiconify() 114 | root.lift() 115 | root.focus_force() 116 | # credits to http://stackoverflow.com/questions/3375227/how-to-give-tkinter-file-dialog-focus 117 | 118 | filedir = filedialog.askdirectory() + '//' 119 | 120 | if len(NumberList)%2 != 0 : #ensures an even amount of print entries by copying last page 121 | NumberList += [ NumberList[-1] ] 122 | 123 | print("\nClick on the active VitalSource window to get started.\nThe program will start in: 8") 124 | for seconds in range(8): 125 | time.sleep(1) 126 | if seconds == 7: 127 | print("Starting now...\n") 128 | break 129 | print(str(8 - (seconds + 1))) 130 | 131 | 132 | 133 | if not(RomanStart == 'No' or RomanStart == 'no'): #if user typed in roman numerals 134 | PageEntry1 = RomanBookList[0] 135 | PageEntry2 = RomanBookList[1] 136 | 137 | pyautogui.hotkey('ctrl', 'p') 138 | pyautogui.press(keys = 'tab', presses = 2, interval = 0.25) 139 | pyautogui.press('delete', 5) 140 | pyautogui.typewrite(PageEntry1) 141 | pyautogui.press('tab') 142 | pyautogui.press('delete', 5) 143 | pyautogui.typewrite(PageEntry2) 144 | pyautogui.typewrite(['tab', 'tab', 'enter', 'enter'], interval = 0.25 ) 145 | pyautogui.typewrite("Ebook", interval = 0.50) 146 | pyautogui.press('enter', interval = 0.5) 147 | time.sleep(0.25) 148 | 149 | print("Page: " + '1' + ' of ' + str(len(RomanBookList) )) 150 | for page in range(2, len(RomanBookList), 2): 151 | pyautogui.hotkey('ctrl', 'p', interval = 0.25) 152 | pyautogui.press('tab', 2, interval = 0.25) 153 | pyautogui.press('delete', 6, interval = 0.25) 154 | pyautogui.typewrite(RomanBookList[page], interval = 0.25) 155 | pyautogui.press('tab', interval = 0.25) 156 | pyautogui.press('delete', 6, interval = 0.25) 157 | pyautogui.typewrite(RomanBookList[page + 1]) 158 | pyautogui.typewrite(['tab', 'tab', 'enter', 'enter'], interval = 0.75) 159 | pyautogui.typewrite("File2", interval = 0.5) 160 | pyautogui.press('enter', interval = 0.5) 161 | while (os.path.isfile(filedir + "Ebook.pdf") != True): 162 | time.sleep(2) 163 | while (os.path.isfile(filedir + "File2.pdf") != True): 164 | time.sleep(2) 165 | try: 166 | pdf1File = open(filedir + 'Ebook.pdf', 'rb') 167 | pdf2File = open(filedir + 'File2.pdf', 'rb') 168 | except: 169 | while (os.path.isfile(filedir + Ebook.pdf) != True): 170 | time.sleep(10) 171 | while (os.path.isfile(filedir + File2.pdf) != True): 172 | time.sleep(10) 173 | 174 | try: #not ideal handling , but it works. A bug that yields OSError(22, 'Invalid argument') should be investigated 175 | pdf1Reader = PyPDF2.PdfFileReader(pdf1File) 176 | except: 177 | time.sleep(5) 178 | pdf1Reader = PyPDF2.PdfFileReader(pdf1File) 179 | 180 | try: 181 | pdf2Reader = PyPDF2.PdfFileReader(pdf2File) 182 | except: 183 | time.sleep(5) 184 | pdf2Reader = PyPDF2.PdfFileReader(pdf2File) 185 | 186 | 187 | pdfWriter = PyPDF2.PdfFileWriter() 188 | for pageNum in range(pdf1Reader.numPages): 189 | pageObj = pdf1Reader.getPage(pageNum) 190 | pdfWriter.addPage(pageObj) 191 | for pageNum in range(pdf2Reader.numPages): 192 | pageObj = pdf2Reader.getPage(pageNum) 193 | pdfWriter.addPage(pageObj) 194 | pdfOutputFile = open(filedir + 'Ebook1.pdf', 'wb') 195 | pdfWriter.write(pdfOutputFile) 196 | pdfOutputFile.close() 197 | pdf1File.close() 198 | pdf2File.close() 199 | os.remove(filedir + 'Ebook.pdf') 200 | os.remove(filedir + 'File2.pdf') 201 | os.rename(filedir + 'Ebook1.pdf', filedir + 'Ebook.pdf') 202 | print("Page: " + str(page + 2) + ' of ' + str(len(RomanBookList))) 203 | print("\nRoman Numerals Done\n") 204 | pyautogui.hotkey('ctrl', 'pagedown', interval = 0.25) 205 | 206 | else: 207 | PageEntry1 = NumberList[0] 208 | PageEntry2 = NumberList[1] 209 | 210 | pyautogui.hotkey('ctrl', 'p') 211 | pyautogui.press(keys = 'tab', presses = 2, interval = 0.25) 212 | pyautogui.press('delete', 5) 213 | pyautogui.typewrite(PageEntry1) 214 | pyautogui.press('tab') 215 | pyautogui.press('delete', 5) 216 | pyautogui.typewrite(PageEntry2) 217 | pyautogui.typewrite(['tab', 'tab', 'enter', 'enter'], interval = 0.25 ) 218 | pyautogui.typewrite("Ebook", interval = 0.50) 219 | pyautogui.press('enter', interval = 0.5) 220 | time.sleep(0.25) 221 | 222 | def NumberProcess(start, inputLastPageList): 223 | for page in range(start, len(NumberList), 2): 224 | pyautogui.hotkey('ctrl', 'p', interval = 0.25) 225 | pyautogui.press('tab', 2, interval = 0.25) 226 | pyautogui.press('delete', 5, interval = 0.25) 227 | pyautogui.typewrite(NumberList[page], interval = 0.25) 228 | pyautogui.press('tab', interval = 0.25) 229 | pyautogui.press('delete', 5, interval = 0.25) 230 | pyautogui.typewrite(NumberList[page + 1]) 231 | pyautogui.typewrite(['tab', 'tab', 'enter', 'enter'], interval = 0.75) 232 | pyautogui.typewrite("File2", interval = 0.5) 233 | pyautogui.press('enter', interval = 0.5) 234 | time.sleep(5) 235 | while (os.path.isfile(filedir + "Ebook.pdf") != True): 236 | time.sleep(2) 237 | while (os.path.isfile(filedir + "File2.pdf") != True): 238 | time.sleep(2) 239 | try: 240 | pdf1File = open(filedir + 'Ebook.pdf', 'rb') 241 | pdf2File = open(filedir + 'File2.pdf', 'rb') 242 | except: 243 | while (os.path.isfile(filedir + Ebook.pdf) != True): 244 | time.sleep(10) 245 | while (os.path.isfile(filedir + File2.pdf) != True): 246 | time.sleep(10) 247 | try: 248 | pdf1Reader = PyPDF2.PdfFileReader(pdf1File) 249 | except: 250 | time.sleep(5) 251 | pdf1Reader = PyPDF2.PdfFileReader(pdf1File) 252 | 253 | try: 254 | pdf2Reader = PyPDF2.PdfFileReader(pdf2File) 255 | except: 256 | time.sleep(5) 257 | pdf2Reader = PyPDF2.PdfFileReader(pdf2File) 258 | 259 | pdfWriter = PyPDF2.PdfFileWriter() 260 | for pageNum in range(pdf1Reader.numPages): 261 | pageObj = pdf1Reader.getPage(pageNum) 262 | pdfWriter.addPage(pageObj) 263 | for pageNum in range(pdf2Reader.numPages): 264 | pageObj = pdf2Reader.getPage(pageNum) 265 | pdfWriter.addPage(pageObj) 266 | pdfOutputFile = open(filedir + 'Ebook1.pdf', 'wb') 267 | pdfWriter.write(pdfOutputFile) 268 | pdfOutputFile.close() 269 | pdf1File.close() 270 | pdf2File.close() 271 | try: 272 | os.remove(filedir + 'Ebook.pdf') 273 | except: 274 | time.sleep(10) 275 | os.remove(filedir + 'Ebook.pdf') 276 | 277 | try: 278 | os.remove(filedir + 'File2.pdf') 279 | except: 280 | time.sleep(10) 281 | os.remove(filedir + 'File2.pdf') 282 | 283 | try: 284 | os.rename(filedir + 'Ebook1.pdf', filedir + 'Ebook.pdf') 285 | except: 286 | time.sleep(10) 287 | os.rename(filedir + 'Ebook1.pdf', filedir + 'Ebook.pdf') 288 | 289 | print("Page: " + str(page + 2) + ' of ' + str(len(NumberList) )) 290 | 291 | if page in inputLastPageList or (page+1) in inputLastPageList : #checks if a last page was found 292 | pyautogui.hotkey('ctrl', 'pagedown', interval = 0.25) 293 | 294 | if not (RomanStart == 'No' or RomanStart == 'no'): 295 | NumberProcess(0, chapLastPageList) 296 | else: 297 | NumberProcess(2, chapLastPageList) 298 | elapsed_time = time.time() - start_time 299 | print("\nDone!") 300 | print("This took " + "%.2f" % (elapsed_time/3600) + " hours.") 301 | 302 | if __name__ == "__main__": main() 303 | --------------------------------------------------------------------------------