|
| 1 | +from os import path,getenv,listdir |
| 2 | +from setuptools import Command |
| 3 | +from subprocess import check_call |
| 4 | +from setuptools.command.install import install |
| 5 | +from typing import Literal,Optional |
| 6 | +import sys |
| 7 | +from platform import system |
| 8 | + |
| 9 | + |
| 10 | +class BrowserCoreInstaller(Command): |
| 11 | + """ |
| 12 | + install the Browser Core |
| 13 | + """ |
| 14 | + # description = "Install the specified preparser browser core (chromium, firefox, or webkit)" |
| 15 | + # define command |
| 16 | + # user_options = [ |
| 17 | + # ('browser=', None, 'Specify the preparser browser to install: chromium, firefox, or webkit') |
| 18 | + # ] |
| 19 | + |
| 20 | + def initialize_options(self): |
| 21 | + self.browser_list = ['chromium','firefox','webkit'] |
| 22 | + self.installed_browsers = [] |
| 23 | + self.need_recheck_browsers = [] |
| 24 | + self.browser_cache_path = None |
| 25 | + self.preched_installed_browsers = self._get_pre_installed_browsers() |
| 26 | + |
| 27 | + def _get_pre_installed_browsers(self) -> list[str]: |
| 28 | + preched_installed_browsers = [] |
| 29 | + os_type = system() |
| 30 | + browser_cache_path = path.expanduser("~/.cache/ms-playwright/") |
| 31 | + if os_type == "Windows": |
| 32 | + browser_cache_path = path.join(getenv("APPDATA"), "Local", "ms-playwright") |
| 33 | + if path.exists(browser_cache_path): |
| 34 | + self.browser_cache_path = browser_cache_path |
| 35 | + folder_name_list = listdir(self.browser_cache_path) |
| 36 | + for folder_name in folder_name_list: |
| 37 | + abs_path = path.join(self.browser_cache_path, folder_name) |
| 38 | + if path.isdir(abs_path): |
| 39 | + for key in self.browser_list: |
| 40 | + if folder_name.startswith(key): |
| 41 | + preched_installed_browsers.append(key) |
| 42 | + else: |
| 43 | + preched_installed_browsers = [] |
| 44 | + return preched_installed_browsers |
| 45 | + |
| 46 | + |
| 47 | + def precheck_installed_browsers(self): |
| 48 | + self.installed_browsers = [] |
| 49 | + self.need_recheck_browsers = [] |
| 50 | + # get the path |
| 51 | + for browser_name in self.browser_list: |
| 52 | + if browser_name in self.preched_installed_browsers: |
| 53 | + print(f'find that browser {browser_name} of preparser installed !') |
| 54 | + operate_choice = self.check_choice_avalible(f" do you want to reinstall,remove or keep it ? (1 : reinstall, 2: remove , 3: keep.): ",['1','2','3']) |
| 55 | + if operate_choice == "3": |
| 56 | + self.installed_browsers.append(browser_name) |
| 57 | + else: # "1" or "2" |
| 58 | + self.operate_browser("uninstall",browser_name) |
| 59 | + if operate_choice == '1': |
| 60 | + self.operate_browser("install",browser_name) |
| 61 | + self.installed_browsers.append(browser_name) |
| 62 | + else: |
| 63 | + self.need_recheck_browsers.append(browser_name) |
| 64 | + |
| 65 | + |
| 66 | + def init_install_browser(self): |
| 67 | + # if not , just let the user to choose |
| 68 | + print("please choose a preparser browser to install: ") |
| 69 | + print("[1] chromium, [2] firefox, [3] webkit.") |
| 70 | + choice = self.check_choice_avalible(f'please input a number to choose a browser (1/2/3):',['1','2','3']) |
| 71 | + browser = self.browser_list[int(choice)-1] |
| 72 | + self.operate_browser("install",browser) |
| 73 | + return browser |
| 74 | + |
| 75 | + def operate_browser(self,command_type:Literal["install","uninstall"], browser_name:str): |
| 76 | + # install specified browser |
| 77 | + print(f"{command_type}ing preparser browser {browser_name} ...") |
| 78 | + check_call([sys.executable, "-m", "playwright", command_type, browser_name]) |
| 79 | + |
| 80 | + def check_choice_avalible(self, alert_message: str, valid_choices: list[str]) -> Optional[str]: |
| 81 | + while True: |
| 82 | + choice = input(alert_message) |
| 83 | + if choice in valid_choices: |
| 84 | + return choice |
| 85 | + else: |
| 86 | + print(f"Invalid choice, available choices: {','.join(valid_choices)}. Please try again.") |
| 87 | + |
| 88 | + def finalize_options(self): |
| 89 | + if self.installed_browsers.__len__() == 0: |
| 90 | + print("warning: to use preparser, you need at least one of the preparser browsers installed .") |
| 91 | + install_browser = self.init_install_browser() |
| 92 | + self.installed_browsers.append(install_browser) |
| 93 | + |
| 94 | + |
| 95 | + def run(self): |
| 96 | + print("checking weather there were preparser browsers' core installed .....") |
| 97 | + self.precheck_installed_browsers() |
| 98 | + recheck_browsers_number = len(self.need_recheck_browsers) |
| 99 | + total_browsers_number = len(self.browser_list) |
| 100 | + if recheck_browsers_number > 0: |
| 101 | + if recheck_browsers_number < total_browsers_number: |
| 102 | + print(f'there were browsers of preparser not installed {",".join(self.need_recheck_browsers)}.') |
| 103 | + print(f"warning: added more or not won't effect your next process, as you have installed {",".join(self.installed_browsers)} ") |
| 104 | + choice = self.check_choice_avalible('do you still want to add them ? (yes/no) : ',['yes','no']) |
| 105 | + if choice == 'yes': |
| 106 | + for browser in self.need_recheck_browsers: |
| 107 | + to_install_choice = self.check_choice_avalible(f'do you want to install {browser} of preparser ? (yes/no) : ',['yes','no']) |
| 108 | + if to_install_choice == 'yes': |
| 109 | + self.operate_browser("install",browser) |
| 110 | + self.installed_browsers.append(install_browser) |
| 111 | + else: # no browser installed |
| 112 | + install_browser = self.init_install_browser() |
| 113 | + self.installed_browsers.append(install_browser) |
| 114 | + |
| 115 | + |
| 116 | +class PreInstaller(install): |
| 117 | + def run(self): |
| 118 | + print('Prechecking the environment status, before install preparser!!!') |
| 119 | + if 'bdist_wheel' in sys.argv or 'build' in sys.argv: |
| 120 | + # Avoid running the browser installer during the build phase |
| 121 | + print("Skipping browser core installation during build.") |
| 122 | + else: |
| 123 | + # precheck the environment status before install |
| 124 | + print('Prechecking the environment status, before install preparser!!!') |
| 125 | + # Execute playwright install command |
| 126 | + BrowserCoreInstaller(self.distribution).run() |
| 127 | + print("All prechecks finished, begin installing preparser...") |
| 128 | + # excute the default running |
| 129 | + self.run(self) |
| 130 | + |
| 131 | + |
| 132 | + |
0 commit comments