├── requirements-mac.txt ├── requirements-dev.txt ├── requirements.txt ├── assets ├── icon.ico └── icon.png ├── run.py ├── src ├── config.py ├── utils.py ├── gui │ ├── main.py │ └── images.py └── download.py ├── .gitignore ├── README.md └── .github └── workflows └── package.yml /requirements-mac.txt: -------------------------------------------------------------------------------- 1 | PyObjC -------------------------------------------------------------------------------- /requirements-dev.txt: -------------------------------------------------------------------------------- 1 | pyinstaller 2 | ordered-set -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | PySimpleGUI==4.60.3 2 | darkdetect==0.7.1 3 | requests==2.31.0 -------------------------------------------------------------------------------- /assets/icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fedebotu/clone-anonymous-github/HEAD/assets/icon.ico -------------------------------------------------------------------------------- /assets/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fedebotu/clone-anonymous-github/HEAD/assets/icon.png -------------------------------------------------------------------------------- /run.py: -------------------------------------------------------------------------------- 1 | """ 2 | Easily clone/download Anonymous Github repositories from [anonymous.4open.science](anonymous.4open.science) with a GUI interface! 3 | """ 4 | 5 | from src.gui.main import main_page 6 | 7 | 8 | # Run the main GUI app 9 | if __name__ == "__main__": 10 | main_page() 11 | -------------------------------------------------------------------------------- /src/config.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | 4 | # Default configuration 5 | DEFAULT_CONFIG = {'url': 'https://anonymous.4open.science/r/840c8c57-3c32-451e-bf12-0e20be300389/', 6 | 'save_dir': os.getcwd(), 7 | 'max_conns': 256, 8 | 'max_retry': 5} 9 | 10 | 11 | def load_config(): 12 | """Load configuration""" 13 | return DEFAULT_CONFIG 14 | 15 | 16 | def get_config_from_values(values): 17 | """Config from PySimpleGUI values""" 18 | config = DEFAULT_CONFIG.copy() 19 | for key in config.keys(): 20 | try: 21 | value = values[key] 22 | config[key] = value 23 | except Exception as e: 24 | print("Could not get config from values:", e) 25 | continue 26 | return config -------------------------------------------------------------------------------- /src/utils.py: -------------------------------------------------------------------------------- 1 | import threading 2 | import ctypes 3 | 4 | class ThreadWithException(threading.Thread): 5 | """Thread class throwing an exception when stopped""" 6 | def __init__(self, target, args): 7 | threading.Thread.__init__(self) 8 | self.target = target 9 | self.args = args 10 | self.return_value = None # return value of target function 11 | 12 | def run(self): 13 | self.return_value = self.target(*self.args) 14 | 15 | def get_id(self): 16 | 17 | # returns id of the respective thread 18 | if hasattr(self, '_thread_id'): 19 | return self._thread_id 20 | for id, thread in threading._active.items(): 21 | if thread is self: 22 | return id 23 | 24 | def raise_exception(self): 25 | thread_id = self.get_id() 26 | res = ctypes.pythonapi.PyThreadState_SetAsyncExc(thread_id, 27 | ctypes.py_object(SystemExit)) 28 | if res > 1: 29 | ctypes.pythonapi.PyThreadState_SetAsyncExc(thread_id, 0) 30 | print('Exception raise failure') -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # pycharm cache 2 | .idea/ 3 | 4 | # Byte-compiled / optimized / DLL files 5 | __pycache__/ 6 | *.py[cod] 7 | *$py.class 8 | 9 | # C extensions 10 | *.so 11 | 12 | # Distribution / packaging 13 | .Python 14 | build/ 15 | develop-eggs/ 16 | dist/ 17 | downloads/ 18 | eggs/ 19 | .eggs/ 20 | lib/ 21 | lib64/ 22 | parts/ 23 | sdist/ 24 | var/ 25 | wheels/ 26 | pip-wheel-metadata/ 27 | share/python-wheels/ 28 | *.egg-info/ 29 | .installed.cfg 30 | *.egg 31 | MANIFEST 32 | 33 | # PyInstaller 34 | # Usually these files are written by a python script from a template 35 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 36 | *.manifest 37 | *.spec 38 | 39 | # Installer logs 40 | pip-log.txt 41 | pip-delete-this-directory.txt 42 | 43 | # Unit test / coverage reports 44 | htmlcov/ 45 | .tox/ 46 | .nox/ 47 | .coverage 48 | .coverage.* 49 | .cache 50 | nosetests.xml 51 | coverage.xml 52 | *.cover 53 | *.py,cover 54 | .hypothesis/ 55 | .pytest_cache/ 56 | 57 | # Translations 58 | *.mo 59 | *.pot 60 | 61 | # Django stuff: 62 | *.log 63 | local_settings.py 64 | db.sqlite3 65 | db.sqlite3-journal 66 | 67 | # Flask stuff: 68 | instance/ 69 | .webassets-cache 70 | 71 | # Scrapy stuff: 72 | .scrapy 73 | 74 | # Sphinx documentation 75 | docs/_build/ 76 | 77 | # PyBuilder 78 | target/ 79 | 80 | # Jupyter Notebook 81 | .ipynb_checkpoints 82 | 83 | # IPython 84 | profile_default/ 85 | ipython_config.py 86 | 87 | # pyenv 88 | .python-version 89 | 90 | # pipenv 91 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 92 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 93 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 94 | # install all needed dependencies. 95 | #Pipfile.lock 96 | 97 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow 98 | __pypackages__/ 99 | 100 | # Celery stuff 101 | celerybeat-schedule 102 | celerybeat.pid 103 | 104 | # SageMath parsed files 105 | *.sage.py 106 | 107 | # Environments 108 | .env 109 | .venv 110 | env/ 111 | venv/ 112 | ENV/ 113 | env.bak/ 114 | venv.bak/ 115 | 116 | # Spyder project settings 117 | .spyderproject 118 | .spyproject 119 | 120 | # Rope project settings 121 | .ropeproject 122 | 123 | # mkdocs documentation 124 | /site 125 | 126 | # mypy 127 | .mypy_cache/ 128 | .dmypy.json 129 | dmypy.json 130 | 131 | # Pyre type checker 132 | .pyre/ -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Clone Anonymous Github (deprecated) 2 | 3 | > [!CAUTION] 4 | > Now [Anonymous Github](https://github.com/fedebotu/clone-anonymous-github/issues/12) supports downloading repos directly; please use that functionality instead! 5 | 6 | 7 | Easily clone/download Anonymous Github repositories from [anonymous.4open.science](anonymous.4open.science) with a GUI interface. 8 | 9 | _No need for GUI interface? We support command line as well!_ 10 | 11 | > [!IMPORTANT] 12 | > Please take notice of [this Github issue](https://github.com/tdurieux/anonymous_github/issues/24), as it seems that the reason cloning is not implemented is because of server managing costs. Please do not abuse the service and if possible, support [Anonymous Github](https://github.com/tdurieux/anonymous_github)! 13 | 14 | ## Download 15 | [![Latest release](https://img.shields.io/badge/Windows-0078D6?style=for-the-badge&logo=windows&logoColor=white)](https://github.com/fedebotu/clone-anonymous-github/releases/download/0.2.1/Clone-Anonymous-Github-WINDOWS.exe) [![Latest release](https://img.shields.io/badge/mac%20os-000000?style=for-the-badge&logo=apple&logoColor=white)](https://github.com/fedebotu/clone-anonymous-github/releases/download/0.2.1/Clone-Anonymous-Github-MAC.tar) 16 | 17 | ## Usage (GUI) 18 | ### Windows and Mac 19 | For Windows and Mac users: from the [Release Page](https://github.com/fedebotu/clone-anonymous-github/releases/), download and run files that fit your operating system. 20 | **Notice about antivirus**: the executables may be detected as fake positives, so you need to temporarily disable your anti virus program 21 | 22 | ### Linux 23 | First clone the repository and install the requirements (optionally, create a virtual environment) 24 | ```shell 25 | pip install -r requirements.txt 26 | ``` 27 | then, run 28 | 29 | ```shell 30 | python run.py 31 | ``` 32 | 33 | ## Usage (command line) 34 | ```shell 35 | git clone https://github.com/fedebotu/clone-anonymous-github.git && cd clone-anonymous-github 36 | python3 src/download.py --url [YOUR_ANONYMOUS_GITHUB_URL] 37 | ``` 38 | 39 | ## Known "Bugs" 40 | 41 | - The maximum number of downloads is exceeded: (also in [this PR](https://github.com/fedebotu/clone-anonymous-github/pull/5)), there are limitations on the number of downloads every 15 minutes from the same IP address. If this happens, either wait or change your IP (i.e., with a VPN). If you decide to wait: wait for 15 minutes and then start the download again to the same directory. Already downloaded files will be skipped, and 'bad' files will be downloaded. 42 | 43 | 44 | ## Contribute 45 | Feel free to raise issues and submit pull requests! :D 46 | 47 | ## Acknowledgements 48 | Thanks to the original [tdurieux's Anonymous Github project](https://github.com/tdurieux/anonymous_github), [ShoufaChen's Clone Anonymous Github](https://github.com/ShoufaChen/clone-anonymous4open), [kynehc's Clone Anonymous Github](https://github.com/kynehc/clone_anonymous_github) and [cbhua](https://github.com/cbhua) for testing in MacOS! 49 | -------------------------------------------------------------------------------- /.github/workflows/package.yml: -------------------------------------------------------------------------------- 1 | # This workflow will install Python dependencies, run tests and lint with a variety of Python versions 2 | # For more information see: https://help.github.com/actions/language-and-framework-guides/using-python-with-github-actions 3 | 4 | name: Python package 5 | 6 | on: [push, pull_request] 7 | 8 | jobs: 9 | # lint: 10 | # name: Lint python 11 | # runs-on: ubuntu-latest 12 | # steps: 13 | # - uses: actions/checkout@v2 14 | # - uses: actions/setup-python@v2 15 | # - uses: actions/cache@v2 16 | # with: 17 | # path: ~/.cache/pip 18 | # key: ${{ runner.os }}-lint-cache-${{ hashFiles('requirements.txt') }} 19 | # restore-keys: | 20 | # ${{ runner.os }}-lint-cache- 21 | # - name: Install dependencies 22 | # run: | 23 | # python -m pip install --upgrade pip wheel 24 | # python -m pip install prospector pytest -r requirements.txt 25 | # - name: Lint via prospector 26 | # run: python -m prospector 27 | 28 | Windows-Build: 29 | runs-on: windows-latest 30 | # needs: lint 31 | strategy: 32 | fail-fast: false 33 | matrix: 34 | python-version: [3.10.2] 35 | 36 | steps: 37 | - uses: actions/checkout@v2 38 | - name: Cache 39 | uses: actions/cache@v2 40 | with: 41 | # A list of files, directories, and wildcard patterns to cache and restore 42 | path: | 43 | ~\AppData\Local\pip\Cache 44 | ~\AppData\Local\Nuitka\Nuitka 45 | Clone-Anonymous-Github.build 46 | Clone-Anonymous-Github.dist 47 | Clone-Anonymous-Github-build 48 | # An explicit key for restoring and saving the cache 49 | key: ${{ runner.os }}-cache-${{ hashFiles('requirements.txt') }} 50 | restore-keys: | 51 | ${{ runner.os }}-cache- 52 | - name: Set up Python ${{ matrix.python-version }} 53 | uses: actions/setup-python@v2 54 | with: 55 | python-version: ${{ matrix.python-version }} 56 | 57 | - name: Install dependencies 58 | run: | 59 | python -m pip install --upgrade pip wheel 60 | python -m pip install nuitka pytest zstandard -r requirements.txt 61 | - name: Make OneFile 62 | run: | 63 | nuitka --assume-yes-for-downloads --show-scons --no-progress --plugin-enable=tk-inter --disable-console --windows-icon-from-ico=assets/icon.ico --onefile -o Clone-Anonymous-Github.exe run.py 64 | - name: Upload artifact 65 | uses: actions/upload-artifact@v2 66 | with: 67 | name: Windows-Binary 68 | path: Clone-Anonymous-Github.exe 69 | 70 | 71 | MacOS-Build: 72 | runs-on: macos-latest 73 | # needs: lint 74 | strategy: 75 | fail-fast: false 76 | matrix: 77 | python-version: [3.10.2] 78 | 79 | steps: 80 | - uses: actions/checkout@v2 81 | - name: Set up Python ${{ matrix.python-version }} 82 | uses: actions/setup-python@v2 83 | with: 84 | python-version: ${{ matrix.python-version }} 85 | - uses: actions/cache@v2 86 | with: 87 | path: ${{ env.pythonLocation }} 88 | key: ${{ runner.os }}-${{ env.pythonLocation }}-${{ hashFiles('requirements.txt', 'requirements-mac.txt', 'requirements-dev.txt') }} 89 | - name: Install dependencies 90 | run: | 91 | python -m pip install --upgrade pip wheel 92 | python -m pip install pytest -r requirements.txt -r requirements-mac.txt -r requirements-dev.txt 93 | - name: Make OneFile 94 | run: | 95 | pyinstaller --onefile run.py 96 | chmod +x dist/run 97 | - name: Tar file 98 | run: tar -cvf dist/Clone-Anonymous-Github.tar dist/run 99 | - name: Upload artifact 100 | uses: actions/upload-artifact@v2 101 | with: 102 | name: Mac-Binary 103 | path: dist/Clone-Anonymous-Github.tar 104 | 105 | publish: 106 | name: Release 107 | permissions: 108 | contents: write 109 | needs: [Windows-Build, MacOS-Build] 110 | runs-on: ubuntu-latest 111 | if: startsWith(github.ref, 'refs/tags/') 112 | 113 | steps: 114 | - name: Download archived package 115 | uses: actions/download-artifact@v2 116 | with: 117 | path: artifacts 118 | 119 | - name: Rename file name for release 120 | run: | 121 | mv artifacts/Windows-Binary/Clone-Anonymous-Github.exe artifacts/Clone-Anonymous-Github.exe 122 | mv artifacts/Mac-Binary/Clone-Anonymous-Github.tar artifacts/Clone-Anonymous-Github.tar 123 | - name: Release 124 | uses: softprops/action-gh-release@v1 125 | with: 126 | draft: true 127 | body: "Released via Github Actions" 128 | files: | 129 | artifacts/Clone-Anonymous-Github.exe 130 | artifacts/Clone-Anonymous-Github.tar 131 | -------------------------------------------------------------------------------- /src/gui/main.py: -------------------------------------------------------------------------------- 1 | import PySimpleGUI as gui 2 | import webbrowser 3 | import darkdetect 4 | 5 | from src.gui.images import LOGO_B64 6 | from src.download import download_repo 7 | from src.config import load_config, get_config_from_values 8 | from src.utils import ThreadWithException 9 | 10 | DEFAULT_THEME = 'Reddit' 11 | DEFAULT_FONT = 'Calibri 12' 12 | MAX_WIDTH = 60 13 | APP_NAME = "Clone Anonymous Github" 14 | APP_VERSION = "0.3.0" 15 | GITHUB_PAGE = "https://github.com/fedebotu/clone-anonymous-github" 16 | MAIN_TEXT = "Easily clone/download Anonymous Github repositories from anonymous.4open.science with a GUI interface" 17 | MAIN_HELP_TEXT = "Copy and paste the URL of a target repository (should work also from a file, its parent repo will be targeted), select your download folder and press the clone button. You may stop the download thread at any time by pressing the stop button. " 18 | ABOUT_TEXT = 'Easily clone/download Anonymous Github repositories from anonymous.4open.science with a GUI interface\n\nA thanks to all contributors, including tdurieux for the website and ShoufaChen, kynehc for their download scripts!' 19 | HELP_TEXT_VIRUS = "Windows may flag the program as a virus since it contains browser automation. But hey, guess what, it isn`t :) Try to temporarily deactivate or make an exception in Windows Defender." 20 | HELP_TEXT_OTHER = "Did you encounter another bug? Feel free to search/open an issue on GitHub!" 21 | 22 | # Set theme 23 | if not darkdetect.isDark(): 24 | gui.theme("LightGrey") 25 | BACKGROUND_COLOR = "#232020" 26 | INPUT_BACKGROUND_COLOR = '#ADD8E6' 27 | gui.theme_background_color(BACKGROUND_COLOR) 28 | gui.theme_text_element_background_color(BACKGROUND_COLOR) 29 | gui.theme_text_color("White") 30 | gui.theme_button_color((BACKGROUND_COLOR, INPUT_BACKGROUND_COLOR)) 31 | gui.theme_input_background_color(INPUT_BACKGROUND_COLOR) 32 | gui.theme_input_text_color('#000000') 33 | TAB_TEXT_COLOR="Black" 34 | else: 35 | BACKGROUND_COLOR = "#FAFAFA" 36 | INPUT_BACKGROUND_COLOR = '#0079D3' 37 | TAB_TEXT_COLOR="White" 38 | gui.theme("LightGrey") 39 | 40 | 41 | def main_page(): 42 | """Main page""" 43 | 44 | config = load_config() 45 | 46 | layout_tab1 = [ 47 | [gui.Text('Clone Anonymous Github', font='Calibri 14')], 48 | [gui.Text(MAIN_TEXT, size=(MAX_WIDTH, 2))], 49 | [gui.Text('Get started', font='Calibri 12')], 50 | [gui.Text(MAIN_HELP_TEXT, size=(MAX_WIDTH, 5))], 51 | [gui.Text(f'Target URL')], 52 | [gui.InputText('', key='url', tooltip='Your Anonymous Github URL you want to clone')], 53 | [gui.Text('Choose download folder', justification='right')], 54 | [gui.InputText(config['save_dir'], key='save_dir'), gui.FolderBrowse(tooltip='Choose target download folder')] 55 | ] 56 | 57 | layout_tab2 = [ 58 | [gui.Text('Maximum connections')], 59 | [gui.Slider(range=(1, 512), default_value=config['max_conns'], orientation='h', size=(MAX_WIDTH//2, 10), key='max_conns', tooltip='Maximum number of concurrent connections')], 60 | [gui.Text('Maximum retries')], 61 | [gui.Slider(range=(1, 10), default_value=config['max_retry'], orientation='h', size=(MAX_WIDTH//2, 10), key='max_retry', tooltip='Maximum number of retries for each file')] 62 | ] 63 | 64 | layout_tab3 = [ 65 | [gui.Text('Virus Detection',font='Calibri 16')], 66 | [gui.Text(HELP_TEXT_VIRUS, size=(MAX_WIDTH, 4), enable_events=True)], 67 | [gui.Text('Other Bugs',font='Calibri 16')], 68 | [gui.Text(HELP_TEXT_OTHER, size=(MAX_WIDTH, 4), enable_events=True)], 69 | [gui.Button("Github Issues")], 70 | ] 71 | 72 | layout_tab4 = [ 73 | [gui.Text(APP_NAME, font="Calibri 18")], 74 | [gui.Column([[gui.Image(data=LOGO_B64, size=(150,150), subsample=(2))]], justification='center')], 75 | [gui.Text(ABOUT_TEXT, size=(MAX_WIDTH, 6))], 76 | [gui.Text(f"Application version: {APP_VERSION}",font=DEFAULT_FONT)], 77 | [gui.Button("Github Repository"),gui.Button("Official Anonymous Github Page")], 78 | ] 79 | 80 | layout = [[gui.TabGroup([[gui.Tab('Main', layout_tab1, title_color='Blue', 81 | tooltip='Main settings', background_color=BACKGROUND_COLOR), 82 | gui.Tab('Advanced Settings', layout_tab2, title_color='Blue', 83 | tooltip='Extra stuff you might want to look into', background_color=BACKGROUND_COLOR), 84 | gui.Tab('Help', layout_tab3, title_color='Blue', 85 | tooltip='For quick help', background_color=BACKGROUND_COLOR), 86 | gui.Tab('About', layout_tab4, title_color='Blue', 87 | tooltip='About page and details', background_color=BACKGROUND_COLOR), 88 | ]], background_color=BACKGROUND_COLOR, tab_background_color=INPUT_BACKGROUND_COLOR, title_color=TAB_TEXT_COLOR)], 89 | 90 | [[gui.Text('Debug window', font=("Calibri", 18))], 91 | [gui.Multiline("", size=(MAX_WIDTH, 20), autoscroll=True, reroute_stdout=True, reroute_stderr=True, key='STDOUT', disabled=True)], 92 | [gui.Button('Clone', tooltip='Run program with current configuration'), gui.Button('Stop', tooltip='Stop current run'), gui.Button('Exit')],]] 93 | 94 | 95 | window = gui.Window(APP_NAME, layout, icon=LOGO_B64) 96 | 97 | thread = None 98 | driver = None 99 | while True: 100 | event, values = window.read(timeout=10) 101 | 102 | if event == 'Clone': 103 | print('Starting downloads...') 104 | config = get_config_from_values(values) 105 | thread = ThreadWithException(target=download_repo, args=(config,)) 106 | thread.start() 107 | 108 | elif event == 'Stop': 109 | if thread: 110 | thread.raise_exception() 111 | print("Run was manually terminated") 112 | thread = None 113 | else: 114 | print("No thread is currently running") 115 | 116 | elif event == "Github Repository": 117 | webbrowser.open(GITHUB_PAGE,2) 118 | elif event == "Official Anonymous Github Page": 119 | webbrowser.open("https://anonymous.4open.science/",2) 120 | elif event == "Github Issues": 121 | webbrowser.open(GITHUB_PAGE+'/issues',2) 122 | elif event == gui.WIN_CLOSED or event == 'Exit': 123 | break 124 | 125 | print("Closing remaing threads and windows...") 126 | if thread: thread.raise_exception() 127 | if driver: 128 | # driver.close() 129 | driver.quit() 130 | window.close() 131 | exit() 132 | 133 | 134 | 135 | if __name__ == "__main__": 136 | main_page() -------------------------------------------------------------------------------- /src/download.py: -------------------------------------------------------------------------------- 1 | import requests 2 | import os 3 | from time import sleep 4 | import concurrent.futures 5 | from functools import partial 6 | import threading 7 | 8 | 9 | 10 | class RequestLimitReached(Exception): 11 | """Exception raised when the request limit is reached.""" 12 | pass 13 | 14 | def dict_parse(dic, pre=None): 15 | pre = pre[:] if pre else [] 16 | if isinstance(dic, dict): 17 | for key, value in dic.items(): 18 | if isinstance(value, dict): 19 | for d in dict_parse(value, pre + [key]): 20 | yield d 21 | else: 22 | yield pre + [key, value] 23 | else: 24 | yield pre + [dic] 25 | 26 | 27 | def get_dict_vals(test_dict, key_list): 28 | for i, j in test_dict.items(): 29 | if i in key_list: 30 | yield (i, j) 31 | yield from [] if not isinstance(j, dict) else get_dict_vals(j, key_list) 32 | 33 | 34 | def format_file_size(size, decimals=2, binary_system=False): 35 | if binary_system: 36 | units = ['B', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB'] 37 | largest_unit = 'YiB' 38 | step = 1024 39 | else: 40 | units = ['B', 'kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB'] 41 | largest_unit = 'YB' 42 | step = 1000 43 | for unit in units: 44 | if size < step: 45 | return ('%.' + str(decimals) + 'f %s') % (size, unit) 46 | size /= step 47 | return ('%.' + str(decimals) + 'f %s') % (size, largest_unit) 48 | 49 | 50 | def check_file_authentic(save_path): 51 | """Check text file existed and authentic""" 52 | if not os.path.exists(save_path): 53 | return False 54 | 55 | # Jump up for these file types because we cannot determine these file types are downloaded correctly or not 56 | jump_list = ['.png', '.jpg', '.gif', '.mp4'] 57 | if True in [save_path.endswith(x) for x in jump_list]: 58 | return True 59 | 60 | # Test file is downloaded okay 61 | try: 62 | with open(save_path, "rt") as f: 63 | if f.readline() != "You can only make 350 requests every 15min. Please try again later.": 64 | return True 65 | return False 66 | except Exception: 67 | return False 68 | 69 | 70 | def req_url(dl_file, max_retry=5, headers=None, proxies=None, wait_event=None): 71 | """Download file""" 72 | url = dl_file[0] 73 | save_path = dl_file[1] 74 | 75 | if check_file_authentic(save_path): 76 | return f"File {save_path} existed & authentic" 77 | 78 | # Check Windows or Unix (Mac+Linux); nt is Windows 79 | if os.name == 'nt': 80 | divider = '\\' 81 | else: 82 | divider = '/' 83 | save_dir = divider.join(save_path.split(divider)[:-1]) 84 | if not os.path.exists(save_dir) and save_dir: 85 | try: 86 | os.makedirs(save_dir) 87 | except OSError: 88 | pass 89 | 90 | headers = headers if headers else { 91 | "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.2 Safari/605.1.15" 92 | } 93 | proxies = proxies if proxies else { "http": "", "https":"", } 94 | 95 | attempt = 0 96 | while attempt < max_retry: 97 | if wait_event.is_set(): 98 | print(f"Waiting due to rate limit, attempt {attempt}") 99 | wait_event.wait() # Wait until the event is cleared 100 | try: 101 | r = requests.get(url, headers=headers, proxies=proxies) 102 | if r.text.startswith("You can only make 350 requests every 15min"): 103 | wait_event.set() 104 | print(f"Request limit reached, waiting for 15 minutes. Attempt {attempt}") 105 | sleep(15 * 60) 106 | wait_event.clear() # Clear the event to resume all threads 107 | attempt += 1 108 | continue 109 | with open(save_path, "wb") as f: 110 | f.write(r.content) 111 | return 'Downloaded: ' + str(save_path) 112 | except Exception as e: 113 | exception = e 114 | sleep(0.4) 115 | attempt += 1 116 | return 'File request exception (retry {}): {} - {}'.format(attempt, exception, save_path) 117 | 118 | 119 | 120 | 121 | def download_repo(config): 122 | """Download Anonymous Github repo""" 123 | 124 | url = config['url'] 125 | save_dir = config['save_dir'] 126 | max_conns = config['max_conns'] 127 | max_retry = config['max_retry'] 128 | proxies = {"http": config['proxies'], "https": config['proxies']} 129 | verbose = config['verbose'] 130 | 131 | name = url.split('/')[4] 132 | save_dir = os.path.join(save_dir, name) 133 | 134 | print("=====================================") 135 | print("Cloning project:" + name) 136 | 137 | list_url = "https://anonymous.4open.science/api/repo/"+ name +"/files/" 138 | headers = { 139 | "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.2 Safari/605.1.15" 140 | } 141 | resp = requests.get(url=list_url, headers=headers, proxies=proxies) 142 | file_list = resp.json() 143 | 144 | sizes = [s[1] for s in get_dict_vals(file_list, ['size'])] 145 | print("Downloading {} files, tot: {}:".format(len(sizes), format_file_size(sum((sizes))))) 146 | print("=====================================") 147 | 148 | dl_url = "https://anonymous.4open.science/api/repo/"+ name +"/file/" 149 | files = [] 150 | out = [] 151 | for file in dict_parse(file_list): 152 | file_path = os.path.join(*file[-len(file):-2]) # * operator to unpack the arguments out of a list 153 | save_path = os.path.join(save_dir, file_path) 154 | file_url = os.path.join(dl_url, file_path).replace("\\","/") # replace \ with / for Windows compatibility 155 | files.append((file_url, save_path)) 156 | 157 | partial_req = partial(req_url, max_retry=max_retry, headers=headers, proxies=proxies) 158 | wait_event = threading.Event() 159 | with concurrent.futures.ThreadPoolExecutor(max_workers=max_conns) as executor: 160 | partial_req = partial(req_url, max_retry=max_retry, headers=headers, proxies=proxies, wait_event=wait_event) 161 | future_to_url = {executor.submit(partial_req, dl_file): dl_file for dl_file in files} 162 | for future in concurrent.futures.as_completed(future_to_url): 163 | try: 164 | data = future.result() 165 | except Exception as exc: 166 | data = str(type(exc)) 167 | finally: 168 | out.append(data) 169 | if verbose or "existed & authentic" not in data: 170 | print(data) 171 | print("=====================================") 172 | print("Files saved to: " + save_dir) 173 | print("=====================================") 174 | 175 | 176 | if __name__ == "__main__": 177 | import argparse 178 | parser = argparse.ArgumentParser(description='Download Anonymous Github repo') 179 | parser.add_argument('--url', type=str, help='Anonymous Github repo url') 180 | parser.add_argument('--save_dir', type=str, default='.', help='Save directory') 181 | parser.add_argument('--max_conns', type=int, default=10, help='Max connections') 182 | parser.add_argument('--max_retry', type=int, default=5, help='Max retries') 183 | parser.add_argument('--proxies', type=str, default='', help='Proxies used for connection') 184 | parser.add_argument('--verbose', type=bool, default=False, help='Display skipped files or not') 185 | args = parser.parse_args() 186 | download_repo(args.__dict__) 187 | -------------------------------------------------------------------------------- /src/gui/images.py: -------------------------------------------------------------------------------- 1 | # Images in base64 format 2 | LOGO_B64 = b"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" --------------------------------------------------------------------------------