├── .editorconfig ├── .gitignore ├── .travis.yml ├── .tx └── config ├── AUTHORS.md ├── CHANGELOG.md ├── CONTRIBUTING.md ├── LICENSE ├── MANIFEST.in ├── Makefile ├── README.md ├── conf └── pacman-mirrors.conf ├── docs ├── index.md ├── installation.md └── usage.md ├── locale ├── be │ └── LC_MESSAGES │ │ └── pacman_mirrors.po ├── bg │ └── LC_MESSAGES │ │ └── pacman_mirrors.po ├── ca │ └── LC_MESSAGES │ │ └── pacman_mirrors.po ├── cs │ └── LC_MESSAGES │ │ └── pacman_mirrors.po ├── cy │ └── LC_MESSAGES │ │ └── pacman_mirrors.po ├── da │ └── LC_MESSAGES │ │ └── pacman_mirrors.po ├── de │ └── LC_MESSAGES │ │ └── pacman_mirrors.po ├── el │ └── LC_MESSAGES │ │ └── pacman_mirrors.po ├── es │ └── LC_MESSAGES │ │ └── pacman_mirrors.po ├── es_419 │ └── LC_MESSAGES │ │ └── pacman_mirrors.po ├── es_ES │ └── LC_MESSAGES │ │ └── pacman_mirrors.po ├── fr │ └── LC_MESSAGES │ │ └── pacman_mirrors.po ├── he │ └── LC_MESSAGES │ │ └── pacman_mirrors.po ├── hr │ └── LC_MESSAGES │ │ └── pacman_mirrors.po ├── hr_HR │ └── LC_MESSAGES │ │ └── pacman_mirrors.po ├── hu │ └── LC_MESSAGES │ │ └── pacman_mirrors.po ├── id_ID │ └── LC_MESSAGES │ │ └── pacman_mirrors.po ├── is │ └── LC_MESSAGES │ │ └── pacman_mirrors.po ├── is_IS │ └── LC_MESSAGES │ │ └── pacman_mirrors.po ├── it │ └── LC_MESSAGES │ │ └── pacman_mirrors.po ├── ja │ └── LC_MESSAGES │ │ └── pacman_mirrors.po ├── lt │ └── LC_MESSAGES │ │ └── pacman_mirrors.po ├── nb │ └── LC_MESSAGES │ │ └── pacman_mirrors.po ├── nl │ └── LC_MESSAGES │ │ └── pacman_mirrors.po ├── pacman_mirrors.pot ├── pl │ └── LC_MESSAGES │ │ └── pacman_mirrors.po ├── pt │ └── LC_MESSAGES │ │ └── pacman_mirrors.po ├── pt_BR │ └── LC_MESSAGES │ │ └── pacman_mirrors.po ├── pt_PT │ └── LC_MESSAGES │ │ └── pacman_mirrors.po ├── ro │ └── LC_MESSAGES │ │ └── pacman_mirrors.po ├── ru_RU │ └── LC_MESSAGES │ │ └── pacman_mirrors.po ├── sk │ └── LC_MESSAGES │ │ └── pacman_mirrors.po ├── sr │ └── LC_MESSAGES │ │ └── pacman_mirrors.po ├── sv │ └── LC_MESSAGES │ │ └── pacman_mirrors.po ├── tr │ └── LC_MESSAGES │ │ └── pacman_mirrors.po ├── tr_TR │ └── LC_MESSAGES │ │ └── pacman_mirrors.po ├── uk │ └── LC_MESSAGES │ │ └── pacman_mirrors.po ├── uk_UA │ └── LC_MESSAGES │ │ └── pacman_mirrors.po ├── zh_CN │ └── LC_MESSAGES │ │ └── pacman_mirrors.po └── zh_TW │ └── LC_MESSAGES │ └── pacman_mirrors.po ├── man ├── pacman-mirrors.8.gz └── pacman-mirrors.8.html ├── mkdocs.yml ├── pacman_mirrors ├── __init__.py ├── api │ ├── __init__.py │ ├── api_handler.py │ └── apifn.py ├── builder │ ├── __init__.py │ ├── common.py │ ├── fasttrack.py │ └── interactive.py ├── config │ ├── __init__.py │ └── configuration.py ├── constants │ ├── __init__.py │ ├── colors.py │ └── txt.py ├── dialogs │ ├── __init__.py │ ├── consoleui.py │ └── graphicalui.py ├── functions │ ├── __init__.py │ ├── cliFn.py │ ├── configFn.py │ ├── consoleFn.py │ ├── convertFn.py │ ├── countryFn.py │ ├── customFn.py │ ├── defaultFn.py │ ├── fileFn.py │ ├── filterFn.py │ ├── httpFn.py │ ├── jsonFn.py │ ├── outputFn.py │ ├── printFn.py │ ├── testMirrorFn.py │ ├── util.py │ └── validFn.py ├── mirrors │ ├── __init__.py │ └── mirror.py ├── pacman_mirrors.py └── translation │ ├── __init__.py │ ├── custom_help_formatter.py │ └── i18n.py ├── requirements.txt ├── scripts └── pacman-mirrors ├── setup.cfg ├── setup.py ├── share └── mirrors.json ├── site ├── 404.html ├── css │ ├── base.css │ ├── bootstrap-custom.min.css │ ├── font-awesome-4.5.0.css │ └── highlight.css ├── fonts │ ├── fontawesome-webfont.eot │ ├── fontawesome-webfont.svg │ ├── fontawesome-webfont.ttf │ ├── fontawesome-webfont.woff │ ├── fontawesome-webfont.woff2 │ ├── glyphicons-halflings-regular.eot │ ├── glyphicons-halflings-regular.svg │ ├── glyphicons-halflings-regular.ttf │ ├── glyphicons-halflings-regular.woff │ └── glyphicons-halflings-regular.woff2 ├── img │ ├── favicon.ico │ └── grid.png ├── index.html ├── installation │ └── index.html ├── js │ ├── base.js │ ├── bootstrap-3.0.3.min.js │ ├── highlight.pack.js │ └── jquery-1.10.2.min.js ├── search │ ├── lunr.min.js │ ├── mustache.min.js │ ├── require.js │ ├── search-results-template.mustache │ ├── search.js │ ├── search_index.json │ └── text.js ├── sitemap.xml └── usage │ └── index.html ├── tests ├── .gitignore ├── README.md ├── __init__.py ├── apitest.sh ├── mock │ ├── etc │ │ ├── .gitignore │ │ ├── pacman-mirrors.conf │ │ └── pacman.d │ │ │ └── .gitignore │ ├── usr │ │ ├── .gitignore │ │ └── share │ │ │ └── pacman-mirrors │ │ │ └── .gitignore │ └── var │ │ └── .gitignore ├── mock_configuration.py ├── test-checkpoints.md ├── test-pacman-mirrors-output.sh ├── test_command_line_parse.py ├── test_default_config.py ├── test_httpfn.py ├── test_inital_values.py ├── test_pacman_mirrors.py ├── test_txt_colors.py ├── test_txt_error_types.py ├── test_txt_help_arg_messages.py ├── test_txt_interactive_messages.py ├── test_txt_message_types.py ├── test_txt_messages.py ├── test_txt_mirror_status.py ├── test_txt_non_translatable.py ├── test_txt_options.py └── test_txt_special_words.py └── tox.ini /.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | 3 | root = true 4 | 5 | [*] 6 | indent_style = space 7 | indent_size = 4 8 | trim_trailing_whitespace = true 9 | insert_final_newline = true 10 | charset = utf-8 11 | end_of_line = lf 12 | 13 | [*.bat] 14 | indent_style = tab 15 | end_of_line = crlf 16 | 17 | [LICENSE] 18 | insert_final_newline = false 19 | 20 | [Makefile] 21 | indent_style = tab 22 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.py[cod] 2 | 3 | 4 | # C extensions 5 | *.so 6 | 7 | # Packages 8 | *.egg 9 | *.egg-info 10 | dist 11 | build 12 | eggs 13 | parts 14 | bin 15 | sdist 16 | develop-eggs 17 | .installed.cfg 18 | lib 19 | lib64 20 | 21 | # Installer logs 22 | pip-log.txt 23 | 24 | # Unit test / coverage reports 25 | .coverage 26 | .tox 27 | nosetests.xml 28 | htmlcov 29 | mock/etc/pacman.d/mirrorlist 30 | mock/usr/share/pacman-mirrors/mirrors.json 31 | mock/var/lib/pacman-mirrors/status.json 32 | 33 | # Translations 34 | *.mo 35 | 36 | # Mr Developer 37 | .mr.developer.cfg 38 | .project 39 | .pydevproject 40 | .idea 41 | .vscode 42 | 43 | # Complexity 44 | output/*.html 45 | output/*/index.html 46 | 47 | # Sphinx 48 | docs/_build 49 | pacman_mirrors/__pycache__/ 50 | tests/__pycache__/ 51 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | # Config file for automatic testing at travis-ci.org 2 | 3 | language: python 4 | 5 | python: 6 | - "3.6" 7 | 8 | # command to install dependencies, e.g. pip install -r requirements.txt 9 | install: pip install -r requirements.txt 10 | 11 | # command to run tests, e.g. python setup.py test 12 | script: python setup.py test 13 | 14 | before_install: 15 | - sudo apt-get update -qq 16 | - sudo apt-get install -y python3-gi 17 | -------------------------------------------------------------------------------- /.tx/config: -------------------------------------------------------------------------------- 1 | [main] 2 | host = https://www.transifex.com 3 | 4 | [manjaro-pacman-mirrors.pacman_mirrors] 5 | file_filter = locale//LC_MESSAGES/pacman_mirrors.po 6 | source_file = locale/pacman_mirrors.pot 7 | source_lang = en 8 | type = PO 9 | 10 | -------------------------------------------------------------------------------- /AUTHORS.md: -------------------------------------------------------------------------------- 1 | # Credits 2 | 3 | - Roland Singer 4 | - Esclapion 5 | - Philip Müller 6 | - Ramon Buldó 7 | - Hugo Posnic 8 | - Frede Hundewadt 9 | 10 | Thank you all! ;) 11 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | Contributions are welcome, and they are greatly appreciated! Every 4 | little bit helps, and credit will always be given. 5 | 6 | You can contribute in many ways: 7 | 8 | ## Types of Contributions 9 | 10 | ### Report Bugs 11 | 12 | Report bugs at https://github.com/manjaro/pacman-mirrors/issues. 13 | 14 | If you are reporting a bug, please include: 15 | - Your operating system name and version. 16 | - Any details about your local setup that might be helpful in troubleshooting. 17 | - Detailed steps to reproduce the bug. 18 | 19 | ### Fix Bugs 20 | 21 | Look through the GitHub issues for bugs. Anything tagged with "bug" 22 | is open to whoever wants to implement it. 23 | 24 | ### Implement Features 25 | 26 | Look through the GitHub issues for features. Anything tagged with "feature" 27 | is open to whoever wants to implement it. 28 | 29 | ### Write Documentation 30 | 31 | pacman-mirrors could always use more documentation, whether as part of the 32 | official pacman-mirrors docs, in docstrings, or even on the web in blog posts, 33 | articles, and such. 34 | 35 | ### Translations 36 | 37 | Help us to ship pacman-mirrors in your language by helping our translators on [Transifex](https://www.transifex.com/manjarolinux/manjaro-pacman-mirrors/dashboard/). 38 | 39 | ### Submit Feedback 40 | 41 | The best way to send feedback is to file an issue at https://github.com/manjaro/pacman-mirrors/issues. 42 | 43 | If you are proposing a feature: 44 | - Explain in detail how it would work. 45 | - Keep the scope as narrow as possible, to make it easier to implement. 46 | - Remember that this is a volunteer-driven project, and that contributions 47 | are welcome :) 48 | 49 | ## Get Started! 50 | 51 | Ready to contribute? Here's how to set up `pacman-mirrors` for local development. 52 | 53 | 1. Fork the `pacman-mirrors` repo on GitHub. 54 | 2. Clone your fork locally: 55 | 56 | $ `git clone git@github.com:your_name_here/pacman-mirrors.git` 57 | 58 | 3. Install your local copy into a virtualenv. Assuming you have [virtualenvwrapper](https://virtualenvwrapper.readthedocs.io/en/latest/) installed, this is how you set up your fork for local development: 59 | - $ `mkvirtualenv pacman-mirrors` 60 | - $ `cd pacman-mirrors/` 61 | - $ `python setup.py develop` 62 | 63 | 4. Create a branch for local development: 64 | 65 | $ `git checkout -b name-of-your-bugfix-or-feature` 66 | 67 | Now you can make your changes locally. 68 | 69 | 5. When you're done making changes, check that your changes pass flake8 and the tests, including testing other Python versions with tox: 70 | - $ `flake8 pacman-mirrors tests` 71 | - $ `python setup.py test` 72 | - $ `tox` 73 | 74 | To get flake8 and tox, just pip install them into your virtualenv. 75 | 76 | 6. Commit your changes and push your branch to GitHub: 77 | - $ `git add .` 78 | - $ `git commit -m "Your detailed description of your changes."` 79 | - $ `git push origin name-of-your-bugfix-or-feature` 80 | 81 | 7. Submit a pull request through the GitHub website. 82 | 83 | ## Pull Request Guidelines 84 | 85 | Before you submit a pull request, check that it meets these guidelines: 86 | 87 | 1. The pull request should include tests. 88 | 2. If the pull request adds functionality, the docs should be updated. Put 89 | your new functionality into a function with a docstring, and add the 90 | feature to the list in README.md. 91 | 3. The pull request should work for Python 3.4+, and for PyPy. Check 92 | https://travis-ci.org/manjaro/pacman-mirrors/pull_requests 93 | and make sure that the tests pass for all supported Python versions. 94 | 95 | ## Tips 96 | 97 | To run a subset of tests: 98 | 99 | $ `python -m unittest tests.test_pacman_mirrors` 100 | 101 | Developing environment 102 | 103 | 1. An editor of choice e.g. 104 | * Visual Studio Code `yaourt -S visual-studio-code` 105 | * PyCharm Community `pacman -Syu pycharm-community` 106 | 2. Pandoc converter `pacman -Syu pandoc` 107 | 3. Python environment 108 | ``` 109 | sudo pacman -Syu python-pip 110 | sudo pip install virtualenvwrapper 111 | mkvirtualenv pacman-mirrors 112 | python setup.py develop 113 | pip install mkdocs 114 | pip install tox 115 | pip install coverage 116 | pip install babel 117 | pip install flake8 118 | pip install npyscreen 119 | pip install transifex-client 120 | 121 | ``` 122 | -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | include AUTHORS.md 2 | include CONTRIBUTING.md 3 | include CHANGELOG.md 4 | include LICENSE 5 | include README.md 6 | include man/pacman-mirrors.8 7 | include share/mirrors.json 8 | include scripts/pacman-mirrors 9 | 10 | recursive-include tests * 11 | recursive-exclude * __pycache__ 12 | recursive-exclude * *.py[co] 13 | 14 | recursive-include docs *.md 15 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: clean-pyc clean-build docs clean 2 | 3 | help: 4 | @echo "clean - remove all build, test, coverage and Python artifacts" 5 | @echo "clean-build - remove build artifacts" 6 | @echo "clean-pyc - remove Python file artifacts" 7 | @echo "clean-test - remove test and coverage artifacts" 8 | @echo "lint - check style with flake8" 9 | @echo "test - run tests quickly with the default Python" 10 | @echo "test-all - run tests on every Python version with tox" 11 | @echo "coverage - check code coverage quickly with the default Python" 12 | @echo "docs - generate MkDocs HTML documentation, man page using Pandoc, including API docs" 13 | @echo "release - package and upload a release" 14 | @echo "dist - package" 15 | @echo "install - install the package to the active Python's site-packages" 16 | @echo "pot-file - extract messages to locale/pacman_mirrors.pot" 17 | @echo "push-pot - push pot file to transifex" 18 | @echo "pull-po - pull all translations from transifex" 19 | @echo "mo-files - generate .mo files" 20 | 21 | clean: clean-build clean-pyc clean-test 22 | 23 | clean-build: 24 | rm -fr build/ 25 | rm -fr dist/ 26 | rm -fr .eggs/ 27 | find . -name '*.egg-info' -exec rm -fr {} + 28 | find . -name '*.egg' -exec rm -f {} + 29 | 30 | clean-pyc: 31 | find . -name '*.pyc' -exec rm -f {} + 32 | find . -name '*.pyo' -exec rm -f {} + 33 | find . -name '*~' -exec rm -f {} + 34 | find . -name '__pycache__' -exec rm -fr {} + 35 | 36 | clean-test: 37 | rm -fr .tox/ 38 | rm -f .coverage 39 | rm -fr htmlcov/ 40 | 41 | lint: 42 | flake8 pacman_mirrors tests 43 | 44 | test: 45 | python setup.py test 46 | 47 | test-all: 48 | tox 49 | 50 | coverage: 51 | coverage run --source pacman_mirrors setup.py test 52 | coverage report -m 53 | coverage html 54 | firefox htmlcov/index.html 55 | 56 | docs: 57 | mkdocs build 58 | pandoc -s -t man docs/index.md -o man/pacman-mirrors.8 59 | pandoc docs/index.md -f markdown -t html -s -o man/pacman-mirrors.8.html 60 | gzip man/pacman-mirrors.8 -fq 61 | 62 | man-page: 63 | pandoc -s -t man docs/index.md -o man/pacman-mirrors.8 64 | man man/pacman-mirrors.8 65 | 66 | release: clean 67 | python setup.py sdist upload 68 | python setup.py bdist_wheel upload 69 | 70 | dist: clean 71 | python setup.py sdist 72 | python setup.py bdist_wheel 73 | ls -l dist 74 | 75 | install: clean mo-files 76 | python setup.py install --root=$(DESTDIR) --optimize=1 77 | 78 | pot-file: 79 | python setup.py extract_messages --output-file locale/pacman_mirrors.pot 80 | 81 | push-pot: 82 | tx push -s 83 | 84 | pull-po: 85 | tx pull -a 86 | 87 | mo-files: 88 | python setup.py compile_catalog --directory locale --domain pacman_mirrors 89 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | This repo has been archived. Our code is now hosted at 2 | 3 | https://gitlab.manjaro.org/ 4 | 5 | See you there! 6 | -------------------------------------------------------------------------------- /conf/pacman-mirrors.conf: -------------------------------------------------------------------------------- 1 | ## 2 | ## /etc/pacman-mirrors.conf 3 | ## 4 | 5 | ## Branch Pacman should use (stable, testing, unstable) 6 | # Branch = stable 7 | 8 | ## Generation method 9 | ## 1) rank - rank mirrors depending on their access time 10 | ## 2) random - randomly generate the output mirrorlist 11 | # Method = rank 12 | 13 | ## Define protocols and priority 14 | ## separated by comma 'https,http' or 'http,https' 15 | ## ATM available protocols are: http, https, ftp 16 | ## Not specifying a protocol will ban the protocol from being used 17 | ## If a mirror has more than one protocol defined only the first is written to the mirrorlist 18 | ## Empty means all in reversed alphabetic order 19 | # Protocols = 20 | 21 | ## When set to False - all certificates are accepted. 22 | ## Use only if you fully trust all ssl-enabled mirrors. 23 | # SSLVerify = True 24 | -------------------------------------------------------------------------------- /docs/installation.md: -------------------------------------------------------------------------------- 1 | # Installation 2 | 3 | At the command line: 4 | 5 | $ easy_install pacman-mirrors 6 | 7 | Or, if you have virtualenvwrapper installed:: 8 | 9 | $ mkvirtualenv pacman-mirrors 10 | $ pip install pacman-mirrors 11 | -------------------------------------------------------------------------------- /docs/usage.md: -------------------------------------------------------------------------------- 1 | # Usage 2 | 3 | To use pacman-mirrors in a Python project: 4 | 5 | import pacman_mirrors 6 | -------------------------------------------------------------------------------- /man/pacman-mirrors.8.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/manjaro/pacman-mirrors/b7a0945214e40a1320a75962a4509b354d46b81c/man/pacman-mirrors.8.gz -------------------------------------------------------------------------------- /mkdocs.yml: -------------------------------------------------------------------------------- 1 | site_name: pacman-mirrors 2 | repo_url: https://github.com/manjaro/pacman-mirrors 3 | pages: 4 | - Home: index.md 5 | - Installation: installation.md 6 | - Usage: usage.md 7 | -------------------------------------------------------------------------------- /pacman_mirrors/__init__.py: -------------------------------------------------------------------------------- 1 | __version__ = "4.10.1" 2 | -------------------------------------------------------------------------------- /pacman_mirrors/api/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/manjaro/pacman-mirrors/b7a0945214e40a1320a75962a4509b354d46b81c/pacman_mirrors/api/__init__.py -------------------------------------------------------------------------------- /pacman_mirrors/api/api_handler.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # 3 | # This file is part of pacman-mirrors. 4 | # 5 | # pacman-mirrors is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation, either version 3 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # pacman-mirrors is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with pacman-mirrors. If not, see . 17 | # 18 | # Authors: Frede Hundewadt 19 | 20 | """Pacman-Mirrors API Handler Module""" 21 | 22 | import shutil 23 | import sys 24 | 25 | from pacman_mirrors.constants import txt 26 | from pacman_mirrors.api import apifn 27 | from pacman_mirrors.functions import fileFn 28 | from pacman_mirrors.functions import util 29 | 30 | 31 | def set_config(self, set_pfx=None, set_branch=None, re_branch=False, set_protocols=False, set_url=None): 32 | """ 33 | Api configuration function 34 | :param self: 35 | :param set_pfx: prefix to the config paths 36 | :param set_branch: replace branch in pacman-mirrors.conf 37 | :param re_branch: replace branch in mirror list 38 | :param set_protocols: replace protocols in pacman-mirrors.conf 39 | :param set_url: replace mirror url in mirror list 40 | """ 41 | if set_url is None: 42 | set_url = "" 43 | 44 | if set_pfx is None: 45 | set_pfx = "" 46 | 47 | """ 48 | # apply api configuration to internal configuration object 49 | # Apply prefix if present 50 | """ 51 | if set_pfx: 52 | set_pfx = apifn.sanitize_prefix(set_pfx) 53 | self.config["config_file"] = set_pfx + self.config["config_file"] 54 | self.config["custom_file"] = set_pfx + self.config["custom_file"] 55 | self.config["mirror_file"] = set_pfx + self.config["mirror_file"] 56 | self.config["mirror_list"] = set_pfx + self.config["mirror_list"] 57 | self.config["status_file"] = set_pfx + self.config["status_file"] 58 | self.config["work_dir"] = set_pfx + self.config["work_dir"] 59 | 60 | """ 61 | # First API task: Set branch 62 | """ 63 | if set_branch: 64 | # Apply branch to internal config 65 | self.config["branch"] = set_branch 66 | util.i686_check(self, write=False) 67 | """ 68 | # pacman-mirrors.conf could absent so check for it 69 | """ 70 | if not fileFn.check_existance_of(self.config["config_file"]): 71 | """ 72 | # Copy from host system 73 | """ 74 | fileFn.create_dir(set_pfx + "/etc") 75 | shutil.copyfile("/etc/pacman-mirrors.conf", 76 | self.config["config_file"]) 77 | """ 78 | # Normalize config 79 | """ 80 | apifn.normalize_config(self.config["config_file"]) 81 | """ 82 | # Write branch to config 83 | """ 84 | apifn.write_config_branch(self.config["branch"], 85 | self.config["config_file"], 86 | quiet=self.quiet) 87 | """ 88 | # Second API task: Create a mirror list 89 | """ 90 | if set_url: 91 | """ 92 | # mirror list dir could absent so check for it 93 | """ 94 | fileFn.create_dir(set_pfx + "/etc/pacman.d") 95 | mirror = [ 96 | { 97 | "url": apifn.sanitize_url(set_url), 98 | "country": "BUILDMIRROR", 99 | "protocols": [set_url[:set_url.find(":")]], 100 | "resp_time": "00.00" 101 | } 102 | ] 103 | fileFn.write_mirror_list(self.config, mirror, quiet=self.quiet) 104 | # exit gracefully 105 | sys.exit(0) 106 | """ 107 | # Third API task: Write protocols to config 108 | """ 109 | if set_protocols: 110 | apifn.write_protocols(self.config["protocols"], 111 | self.config["config_file"], 112 | quiet=self.quiet) 113 | """ 114 | # Fourth API task: Rebranch the mirrorl ist 115 | """ 116 | if re_branch: 117 | if not set_branch: 118 | print(".: {} {}".format(txt.ERR_CLR, txt.API_ERROR_BRANCH)) 119 | sys.exit(1) 120 | apifn.write_mirrorlist_branch(self.config["branch"], 121 | self.config["config_file"], 122 | quiet=self.quiet) 123 | 124 | -------------------------------------------------------------------------------- /pacman_mirrors/builder/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/manjaro/pacman-mirrors/b7a0945214e40a1320a75962a4509b354d46b81c/pacman_mirrors/builder/__init__.py -------------------------------------------------------------------------------- /pacman_mirrors/builder/common.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # 3 | # This file is part of pacman-mirrors. 4 | # 5 | # pacman-mirrors is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation, either version 3 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # pacman-mirrors is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with pacman-mirrors. If not, see . 17 | # 18 | # Authors: Frede Hundewadt 19 | 20 | """Pacman-Mirrors Common Mirror List Builder Module""" 21 | 22 | from operator import itemgetter 23 | from random import shuffle 24 | 25 | from pacman_mirrors.constants import txt 26 | from pacman_mirrors.functions import filterFn 27 | from pacman_mirrors.functions import outputFn 28 | from pacman_mirrors.functions import testMirrorFn 29 | 30 | 31 | def build_mirror_list(self): 32 | """ 33 | Generate common mirrorlist 34 | """ 35 | """ 36 | Remove known bad mirrors from the list 37 | mirrors where status.json has -1 for last_sync 38 | """ 39 | mirror_selection = filterFn.filter_bad_mirrors(self.mirrors.mirror_pool) 40 | """ 41 | Create a list based on the content of selected_countries 42 | """ 43 | mirror_selection = filterFn.filter_mirror_country(mirror_selection, 44 | self.selected_countries) 45 | """ 46 | Check the length of selected_countries against the full countrylist 47 | If selected_countries is the lesser then we build a custom pool file 48 | """ 49 | if len(self.selected_countries) < len(self.mirrors.country_pool): 50 | try: 51 | _ = self.selected_countries[0] 52 | outputFn.file_custom_mirror_pool(self, mirror_selection) 53 | except IndexError: 54 | pass 55 | """ 56 | Prototol filtering if applicable 57 | """ 58 | try: 59 | _ = self.config["protocols"][0] 60 | mirror_selection = filterFn.filter_mirror_protocols(mirror_selection, 61 | self.config["protocols"]) 62 | except IndexError: 63 | pass 64 | 65 | """ 66 | Unless the user has provided the --no-status argument we only 67 | write mirrors which are up-to-date for users selected branch 68 | """ 69 | if self.no_status: 70 | pass 71 | else: 72 | mirror_selection = filterFn.filter_user_branch(mirror_selection, 73 | self.config) 74 | 75 | if self.config["method"] == "rank": 76 | mirror_selection = testMirrorFn.test_mirrors(self, 77 | mirror_selection) 78 | mirror_selection = sorted(mirror_selection, 79 | key=itemgetter("resp_time")) 80 | else: 81 | shuffle(mirror_selection) 82 | 83 | """ 84 | Try to write mirrorlist 85 | """ 86 | try: 87 | _ = mirror_selection[0] 88 | outputFn.file_mirror_list(self, mirror_selection) 89 | if self.custom: 90 | print(".: {} {} 'sudo {}'".format(txt.INF_CLR, 91 | txt.REMOVE_CUSTOM_CONFIG, 92 | txt.RESET_ALL)) 93 | if self.no_status: 94 | print("{} {}\n{} {}".format(txt.WRN_CLR, txt.OVERRIDE_STATUS_CHOICE, 95 | txt.WRN_CLR, txt.OVERRIDE_STATUS_MIRROR)) 96 | except IndexError: 97 | print(".: {} {}".format(txt.WRN_CLR, txt.NO_SELECTION)) 98 | print(".: {} {}".format(txt.INF_CLR, txt.NO_CHANGE)) 99 | 100 | -------------------------------------------------------------------------------- /pacman_mirrors/builder/fasttrack.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # 3 | # This file is part of pacman-mirrors. 4 | # 5 | # pacman-mirrors is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation, either version 3 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # pacman-mirrors is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with pacman-mirrors. If not, see . 17 | # 18 | # Authors: Frede Hundewadt 19 | 20 | """Pacman-Mirrors Interactive Fasttrack Mirror List Builder Module""" 21 | 22 | import sys 23 | 24 | from operator import itemgetter 25 | from random import shuffle 26 | 27 | 28 | from pacman_mirrors.constants import txt, colors as color 29 | from pacman_mirrors.functions import filterFn 30 | from pacman_mirrors.functions import httpFn 31 | from pacman_mirrors.functions import outputFn 32 | from pacman_mirrors.functions import util 33 | 34 | 35 | def build_mirror_list(self, number): 36 | """ 37 | Fast-track the mirrorlist by filtering only up-to-date mirrors 38 | The function takes into account the branch selected by the user 39 | either on commandline or in pacman-mirrors.conf. 40 | The function returns a filtered list consisting of a number of mirrors 41 | Only mirrors from the active mirror file is used 42 | either mirrors.json or custom-mirrors.json 43 | """ 44 | """ 45 | remove known bad mirrors (status.json last_sync = -1) 46 | """ 47 | worklist = filterFn.filter_bad_mirrors(self.mirrors.mirror_pool) 48 | """ 49 | filter protocols if user has a selection 50 | """ 51 | if self.config["protocols"]: 52 | worklist = filterFn.filter_mirror_protocols( 53 | worklist, self.config["protocols"]) 54 | 55 | """ 56 | Only pick mirrors which are up-to-date for the system branch 57 | by removing not up-to-date mirrors from the list 58 | """ 59 | up_to_date_mirrors = filterFn.filter_user_branch(worklist, self.config) 60 | """ 61 | Shuffle the list 62 | """ 63 | shuffle(up_to_date_mirrors) 64 | worklist = [] 65 | print(".: {}: {} - {}".format(txt.INF_CLR, 66 | txt.QUERY_MIRRORS, 67 | txt.TAKES_TIME)) 68 | counter = 0 69 | cols, lines = util.terminal_size() 70 | for mirror in up_to_date_mirrors: 71 | if not self.quiet: 72 | message = " ..... {:<15}: {}: {}".format( 73 | mirror["country"], mirror["last_sync"], mirror["url"]) 74 | print("{:.{}}".format(message, cols), end="") 75 | sys.stdout.flush() 76 | resp_time = httpFn.get_mirror_response(mirror["url"], 77 | maxwait=self.max_wait_time, 78 | quiet=self.quiet) 79 | mirror["resp_time"] = resp_time 80 | if float(resp_time) > self.max_wait_time: 81 | if not self.quiet: 82 | print("\r") 83 | else: 84 | if not self.quiet: 85 | print("\r {:<5}{}{} ".format(color.GREEN, 86 | resp_time, 87 | color.ENDCOLOR)) 88 | worklist.append(mirror) 89 | counter += 1 90 | """ 91 | Equality check will stop execution 92 | when the desired number is reached. 93 | In the possible event the first mirror's 94 | response time exceeds the predefined response time, 95 | the loop would stop execution if the check for zero is not present 96 | """ 97 | if counter is not 0 and counter == number: 98 | break 99 | worklist = sorted(worklist, 100 | key=itemgetter("resp_time")) 101 | """ 102 | Try to write mirrorlist 103 | """ 104 | try: 105 | _ = worklist[0] 106 | outputFn.file_mirror_list(self, worklist) 107 | except IndexError: 108 | print(".: {} {}".format(txt.WRN_CLR, txt.NO_SELECTION)) 109 | print(".: {} {}".format(txt.INF_CLR, txt.NO_CHANGE)) 110 | -------------------------------------------------------------------------------- /pacman_mirrors/builder/interactive.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # 3 | # This file is part of pacman-mirrors. 4 | # 5 | # pacman-mirrors is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation, either version 3 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # pacman-mirrors is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with pacman-mirrors. If not, see . 17 | # 18 | # Authors: Frede Hundewadt 19 | 20 | """Pacman-Mirrors Interactive Mirror List Builder Module""" 21 | 22 | from operator import itemgetter 23 | from random import shuffle 24 | 25 | from pacman_mirrors.constants import txt 26 | from pacman_mirrors.functions import convertFn 27 | from pacman_mirrors.functions import filterFn 28 | from pacman_mirrors.functions import outputFn 29 | from pacman_mirrors.functions import testMirrorFn 30 | 31 | 32 | def build_mirror_list(self): 33 | """ 34 | Prompt the user to select the mirrors with a gui. 35 | Outputs a "custom" mirror file 36 | Modify the configuration file to use the "custom" file. 37 | Outputs a pacman mirrorlist, 38 | """ 39 | """ 40 | Remove known bad mirrors from the list 41 | mirrors where status.json has -1 for last_sync or branches is -1,-1,-1 42 | """ 43 | worklist = filterFn.filter_bad_mirrors(self.mirrors.mirror_pool) 44 | """ 45 | It would seem reasonable to implement a filter 46 | based on the users branch and the mirrors update status 47 | On the other hand, the interactive mode is for the user 48 | to have total control over the mirror file. 49 | So though it might seem prudent to only include updated mirrors, 50 | we will not do it when user has selected interactive mode. 51 | The final mirrorfile will include all mirrors selected by the user 52 | The final mirrorlist will exclude (if possible) mirrors not up-to-date 53 | """ 54 | worklist = filterFn.filter_mirror_country(worklist, self.selected_countries) 55 | """ 56 | If config.protols has content, that is a user decision and as such 57 | it has nothing to do with the reasoning regarding mirrors 58 | which might or might not be up-to-date 59 | """ 60 | try: 61 | _ = self.config["protocols"][0] 62 | worklist = filterFn.filter_mirror_protocols( 63 | worklist, self.config["protocols"]) 64 | except IndexError: 65 | pass 66 | 67 | # rank or shuffle the mirrorlist before showing the ui 68 | if not self.default: 69 | if self.config["method"] == "rank": 70 | worklist = testMirrorFn.test_mirrors(self, worklist) 71 | worklist = sorted(worklist, key=itemgetter("resp_time")) 72 | else: 73 | shuffle(worklist) 74 | """ 75 | Create a list for display in ui. 76 | The gui and the console ui expect the supplied list 77 | to be in the old country dictionary format. 78 | { 79 | "country": "country_name", 80 | "resp_time": "m.sss", 81 | "last_sync": "HHh MMm", 82 | "url": "http://server/repo/" 83 | } 84 | Therefore we have to create a list in the old format, 85 | thus avoiding rewrite of the ui and related functions. 86 | We subseqently need to translate the result into: 87 | a. a mirrorfile in the new json format, 88 | b. a mirrorlist in pacman format. 89 | As of version 4.8.x the last sync field contents is a string 90 | with the hours and minutes more human readable eg. 03h 33m 91 | """ 92 | interactive_list = convertFn.translate_pool_to_interactive(worklist) 93 | # import the right ui 94 | if self.no_display: 95 | # in console mode 96 | from pacman_mirrors.dialogs import consoleui as ui 97 | else: 98 | # gobject introspection is present and accounted for 99 | from pacman_mirrors.dialogs import graphicalui as ui 100 | interactive = ui.run(interactive_list, 101 | self.config["method"] == "random", 102 | self.default) 103 | # process user choices 104 | if interactive.is_done: 105 | """ 106 | translate interactive list back to our json format 107 | """ 108 | custom_pool, mirror_list = convertFn.translate_interactive_to_pool(interactive.custom_list, 109 | self.mirrors.mirror_pool, 110 | self.config) 111 | """ 112 | Try selected method on the mirrorlist 113 | """ 114 | try: 115 | _ = mirror_list[0] 116 | if self.default: 117 | if self.config["method"] == "rank": 118 | mirror_list = testMirrorFn.test_mirrors(self, mirror_list) 119 | mirror_list = sorted(mirror_list, key=itemgetter("resp_time")) 120 | else: 121 | shuffle(mirror_list) 122 | except IndexError: 123 | pass 124 | 125 | """ 126 | Try to write the mirrorfile and mirrorlist 127 | """ 128 | try: 129 | _ = custom_pool[0] 130 | self.custom = True 131 | self.config["country_pool"] = ["Custom"] 132 | """ 133 | Writing the custom mirror pool file 134 | """ 135 | outputFn.file_custom_mirror_pool(self, custom_pool) 136 | """ 137 | Unless the user has provided the --no-status argument we only 138 | write mirrors which are up-to-date for users selected branch 139 | """ 140 | if self.no_status: 141 | pass 142 | else: 143 | mirror_list = filterFn.filter_user_branch(mirror_list, self.config) 144 | """ 145 | Writing mirrorlist 146 | If the mirror list is empty because 147 | no up-to-date mirrors exist for users branch 148 | raise IndexError to the outer try-catch 149 | """ 150 | try: 151 | _ = mirror_list[0] 152 | outputFn.file_mirror_list(self, mirror_list) 153 | if self.no_status: 154 | print("{} {}\n{} {}".format(txt.WRN_CLR, txt.OVERRIDE_STATUS_CHOICE, 155 | txt.WRN_CLR, txt.OVERRIDE_STATUS_MIRROR)) 156 | except IndexError: 157 | raise IndexError 158 | except IndexError: 159 | print(".: {} {}".format(txt.WRN_CLR, txt.NO_SELECTION)) 160 | print(".: {} {}".format(txt.INF_CLR, txt.NO_CHANGE)) 161 | -------------------------------------------------------------------------------- /pacman_mirrors/config/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/manjaro/pacman-mirrors/b7a0945214e40a1320a75962a4509b354d46b81c/pacman_mirrors/config/__init__.py -------------------------------------------------------------------------------- /pacman_mirrors/config/configuration.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # 3 | # This file is part of pacman-mirrors. 4 | # 5 | # pacman-mirrors is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation, either version 3 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # pacman-mirrors is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with pacman-mirrors. If not, see . 17 | # 18 | # Authors: Frede Hundewadt 19 | 20 | """Pacman-Mirrors Configuration Module""" 21 | 22 | # http constants 23 | URL_MIRROR_JSON = \ 24 | "https://github.com/manjaro/manjaro-web-repo/raw/master/mirrors.json" 25 | URL_STATUS_JSON = "http://repo.manjaro.org/status.json" 26 | INET_CONN_CHECK_URLS = ["https://wikipedia.org", 27 | "https://github.com", 28 | "https://bitbucket.org"] 29 | # etc files 30 | CONFIG_FILE = "/etc/pacman-mirrors.conf" 31 | MIRROR_LIST = "/etc/pacman.d/mirrorlist" 32 | # pacman-mirrors dir/files 33 | WORK_DIR = "/var/lib/pacman-mirrors/" 34 | USR_DIR = "/usr/share/pacman-mirrors" 35 | CUSTOM_FILE = "/var/lib/pacman-mirrors/custom-mirrors.json" 36 | MIRROR_FILE = "/usr/share/pacman-mirrors/mirrors.json" 37 | STATUS_FILE = "/var/lib/pacman-mirrors/status.json" 38 | # repo constants 39 | BRANCHES = ("stable", "testing", "unstable") 40 | X32_BRANCHES = ("x32-stable", "x32-testing", "x32-unstable") 41 | PROTOCOLS = ("https", "http", "ftp", "ftps") 42 | METHODS = ("rank", "random") 43 | SSL = ("True", "False") 44 | REPO_ARCH = "/$repo/$arch" 45 | # special cases 46 | O_CUST_FILE = "/var/lib/pacman-mirrors/Custom" 47 | TO_BE_REMOVED = "/var/lib/pacman-mirrors/mirrors.json" 48 | -------------------------------------------------------------------------------- /pacman_mirrors/constants/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/manjaro/pacman-mirrors/b7a0945214e40a1320a75962a4509b354d46b81c/pacman_mirrors/constants/__init__.py -------------------------------------------------------------------------------- /pacman_mirrors/constants/colors.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # 3 | # This file is part of pacman-mirrors. 4 | # 5 | # pacman-mirrors is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation, either version 3 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # pacman-mirrors is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with pacman-mirrors. If not, see . 17 | # 18 | # Authors: Esclapion 19 | # Hugo Posnic 20 | 21 | """Pacman-Mirrors Color Constants Module""" 22 | 23 | RED = "\033[1;31m" 24 | GREEN = "\033[1;32m" 25 | YELLOW = "\033[1;33m" 26 | BLUE = "\033[1;34m" 27 | WHITE = "\033[1;37m" 28 | ENDCOLOR = "\033[1;m" 29 | DBG_CLR = "\033[1;46m.: {}\033[1;m".format("DEBUG") 30 | -------------------------------------------------------------------------------- /pacman_mirrors/constants/txt.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # 3 | # This file is part of pacman-mirrors. 4 | # 5 | # pacman-mirrors is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation, either version 3 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # pacman-mirrors is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with pacman-mirrors. If not, see . 17 | # 18 | # Authors: Frede Hundewadt 19 | 20 | """Pacman-Mirrors Text Module""" 21 | 22 | from pacman_mirrors.translation import i18n 23 | 24 | _ = i18n.language.gettext 25 | 26 | # TRANSLATABLE STRINGS 27 | 28 | # MESSAGE TYPES 29 | ERROR = _("ERROR") 30 | INFO = _("INFO") 31 | WARN = _("WARNING") 32 | # ERROR TYPES 33 | HTTP_EXCEPTION = _("HTTPException") 34 | TIMEOUT = _("TIMEOUT") 35 | # SPECIAL WORDS 36 | API = _("API") 37 | BRANCH = _("BRANCH") 38 | COUNTRY = _("COUNTRY") 39 | EXPECTED = _("EXPECTED") 40 | FILE = _("FILE") 41 | METHOD = _("METHOD") 42 | METHODS = _("METHODS") 43 | MISC = _("MISC") 44 | NUMBER = _("NUMBER") 45 | PATH = _("PATH") 46 | PREFIX = _("PREFIX") 47 | PROTO = _("PROTO") 48 | SECONDS = _("SECONDS") 49 | URL = _("URL") 50 | USAGE = _("USAGE") 51 | # HELP MESSAGES 52 | HLP_ARG_API_GET_BRANCH = _("Return branch from configuration") 53 | HLP_ARG_API_PREFIX = _("Set prefix to") 54 | HLP_ARG_API_PROTOCOLS = _("Replace protocols in configuration") 55 | HLP_ARG_API_RE_BRANCH = _("Replace branch in mirrorlist") 56 | HLP_ARG_API_SET_BRANCH = _("Replace branch in configuration") 57 | HLP_ARG_API_URL = _("Replace mirror url in mirrorlist") 58 | HLP_ARG_BRANCH = _("Branch name") 59 | HLP_ARG_COUNTRY = _( 60 | "Comma separated list of countries, from which mirrors will be used") 61 | HLP_ARG_DEFAULT = _("Load default mirror file") 62 | HLP_ARG_FASTTRACK = _( 63 | "Generate mirrorlist with a number of up-to-date mirrors. Overrides") 64 | HLP_ARG_GENERATE = _("Generate mirrorlist with defaults") 65 | HLP_ARG_GEOIP = _("Get current country using geolocation") 66 | HLP_ARG_LIST = _("List all available countries") 67 | HLP_ARG_INTERACTIVE = _("Generate custom mirrorlist") 68 | HLP_ARG_METHOD = _("Generation method") 69 | HLP_ARG_NO_MIRRORLIST = _("Use to skip generation of mirrorlist") 70 | HLP_ARG_QUIET = _("Quiet mode - less verbose output") 71 | HLP_ARG_STATUS = _("Ignore mirror branch status") 72 | HLP_ARG_SYNC = _("Syncronize pacman databases") 73 | HLP_ARG_TIMEOUT = _("Maximum waiting time for server response") 74 | HLP_ARG_VERSION = _("Print the pacman-mirrors version") 75 | # GENERAL MESSAGES 76 | API_CONF_RE_BRANCH = _("Branch in config is changed") 77 | API_CONF_PROTOCOLS = _("Protocols in config is changed") 78 | API_ERROR_BRANCH = _("Re-branch requires a branch to work with") 79 | API_MIRRORLIST_RE_BRANCH = _("Branch in mirror list is changed") 80 | AVAILABLE_COUNTRIES = _("Available countries are") 81 | CANNOT_DOWNLOAD_FILE = _("Could not download from") 82 | CANNOT_READ_FILE = _("Cannot read file") 83 | CANNOT_WRITE_FILE = _("Cannot write file") 84 | CONVERT_CUSTOM_MIRROR_FILE = _("Converting custom mirror file to new format") 85 | CUSTOM_MIRROR_FILE = _("Custom mirror file") 86 | CUSTOM_MIRROR_FILE_SAVED = _("Custom mirror file saved") 87 | CUSTOM_MIRROR_LIST = _("User generated mirror list") 88 | CUSTOM_POOL_EMPTY = _("The custom pool is empty") 89 | DEFAULT_POOL_EMPTY = _("The default pool is empty") 90 | DEPRECATED_ARGUMENT = _("Deprecated argument") 91 | DOES_NOT_EXIST = _("doesn't exist.") 92 | DOWNLOADING_MIRROR_FILE = _("Downloading mirrors from") 93 | FALLING_BACK = _("Falling back to") 94 | INTERNET_DOWN = _("Internet connection appears to be down") 95 | INTERNET_ALTERNATIVE = _("Mirror list is generated using random method") 96 | INVALID_SETTING_IN = _("Invalid setting in") 97 | IS_MISSING = _("is missing") 98 | MIRROR_FILE = _("The mirror file") 99 | MIRROR_LIST_SAVED = _("Mirror list generated and saved to") 100 | MIRROR_LIST_GENERATED_ON = _("Generated on") 101 | MIRROR_LIST_CUSTOM_HEADER = _("custom mirrorlist") 102 | MIRROR_LIST_CUSTOM_RESET = _("to reset custom mirrorlist") 103 | MIRROR_LIST_DEFAULT_HEADER = _("default mirrorlist") 104 | MIRROR_LIST_DEFAULT_MODIFY = _("to modify mirrorlist") 105 | MIRROR_POOL_EMPTY = _("The mirror pool is empty") 106 | MIRROR_RANKING_NA = _("Mirror ranking is not available") 107 | MISSING_ARGUMENT = _("argument is missing") 108 | MUST_BE_ROOT = _("Must have root privileges") 109 | NO_CHANGE = _("The mirrors has not changed") 110 | NO_SELECTION = _("No mirrors in selection") 111 | OPTION = _("Option") 112 | OVERRIDE_STATUS_CHOICE = _("You have chosen to override the status for your system branch.") 113 | OVERRIDE_STATUS_MIRROR = _("Servers in the mirror list might not be up-tp-date.") 114 | PLEASE_USE = _("Please use") 115 | QUERY_MIRRORS = _("Querying mirrors") 116 | RANDOMIZING_SERVERS = _("Randomizing mirror list") 117 | REMOVE_CUSTOM_CONFIG = _("To remove custom config run ") 118 | TAKES_TIME = _("This may take some time") 119 | UNKNOWN_COUNTRY = _("unknown country") 120 | USE_ZERO_FOR_ALL = _("Use 0 for all mirrors") 121 | USING_ALL_MIRRORS = _("Using all mirrors") 122 | USING_CUSTOM_FILE = _("Using custom mirror file") 123 | USING_DEFAULT_FILE = _("Using default mirror file") 124 | WRITING_MIRROR_LIST = _("Writing mirror list") 125 | 126 | # INTERACTIVE MESSAGES 127 | I_TITLE = _("Manjaro mirrors by response time") 128 | I_TITLE_RANDOM = _("Manjaro mirrors in random order") 129 | I_LIST_TITLE = _("Check mirrors for your personal list") 130 | I_USE = _("Use") 131 | I_COUNTRY = _("Country") 132 | I_RESPONSE = _("Resp") 133 | I_LAST_SYNC = _("Sync") 134 | I_URL = _("URL") 135 | I_CANCEL = _("Cancel") 136 | I_CONFIRM = _("OK") 137 | I_CONFIRM_SELECTION = _("Confirm selections") 138 | I_USE_THESE_MIRRORS = _("I want to use these mirrors") 139 | # NON TRANSLATABLE STRINGS 140 | ARGUMENT_API = "-a/--api" 141 | ARGUMENT_DEFAULT = "-d/--default" 142 | ARGUMENT_INTERACTIVE = "-i/--interactive" 143 | HOUSTON = "Houston?! We have a problem." 144 | OVERRIDE_OPT = ": --geoip, --method" 145 | REPO_SERVER = "repo.manjaro.org" 146 | MODIFY_CUSTOM = "pacman-mirrors -id" 147 | MODIFY_DEFAULT = "pacman-mirrors -f [{}]".format(NUMBER) 148 | RESET_ALL = "pacman-mirrors -c all" 149 | PREFIX_TIP = ": $mnt | /mnt/install" 150 | # OPTIONS 151 | OPT_RANDOM = " '-m/--method random' " 152 | OPT_COUNTRY = " 'c/--country' " 153 | # MIRROR RELATED 154 | LASTSYNC_OK = "24:00" # last syncronize in the past 24 hours 155 | LASTSYNC_NA = "9800:00" # last syncronization not available 156 | SERVER_BAD = "9999:99" # default last syncronization status 157 | SERVER_RES = "99.99" # default response status 158 | # MESSAGE WITH COLOR 159 | ERR_CLR = "\033[1;31m{}\033[1;m".format(ERROR) 160 | INF_CLR = "\033[1;37m{}\033[1;m".format(INFO) 161 | WRN_CLR = "\033[1;33m{}\033[1;m".format(WARN) 162 | EXP_CLR = "\033[1;33m{}\033[1;m".format(EXPECTED) 163 | API_ARGUMENTS_ERROR = "{} {}.".format(ARGUMENT_API, MISSING_ARGUMENT) 164 | INTERACTIVE_ARGUMENTS_ERROR = "{} {}.".format(ARGUMENT_INTERACTIVE, MISSING_ARGUMENT) 165 | FASTTRACK_ARGUMENTS_ERROR = "pacman-mirrors: error: argument -s/--no-status: " \ 166 | "not allowed with argument -f/--fasttrack" 167 | -------------------------------------------------------------------------------- /pacman_mirrors/dialogs/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/manjaro/pacman-mirrors/b7a0945214e40a1320a75962a4509b354d46b81c/pacman_mirrors/dialogs/__init__.py -------------------------------------------------------------------------------- /pacman_mirrors/dialogs/consoleui.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # 3 | # This file is part of pacman-mirrors. 4 | # 5 | # pacman-mirrors is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation, either version 3 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # pacman-mirrors is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with pacman-mirrors. If not, see . 17 | # 18 | # Authors: Frede Hundewadt 19 | 20 | """Pacman-Mirrors Console UI Module""" 21 | 22 | from collections import namedtuple 23 | 24 | import npyscreen 25 | 26 | from pacman_mirrors.constants import txt 27 | from pacman_mirrors.functions import consoleFn 28 | from pacman_mirrors.translation import i18n 29 | 30 | _ = i18n.language.gettext 31 | 32 | 33 | class ConsoleUI(npyscreen.NPSAppManaged): 34 | """App""" 35 | 36 | def __init__(self, server_list, random, default): 37 | npyscreen.NPSAppManaged.__init__(self) 38 | # Server lists 39 | self.server_list = server_list 40 | self.custom_list = [] 41 | self.is_done = False 42 | self.random = random 43 | self.default = default 44 | self.title = txt.I_TITLE_RANDOM if random else txt.I_TITLE 45 | if default: 46 | self.title = "Pacman-Mirrors" 47 | 48 | def main(self): 49 | """Main""" 50 | main_server_list = [] 51 | server = namedtuple("Server", ["country", 52 | "resp_time", 53 | "last_sync", 54 | "url"]) 55 | header_cols = ({"country": txt.I_COUNTRY, 56 | "resp_time": txt.I_RESPONSE, 57 | "last_sync": txt.I_LAST_SYNC, 58 | "url": txt.I_URL}) 59 | main_server_list.append(header_cols) 60 | main_server_list.extend(self.server_list) 61 | servers = consoleFn.list_to_tuple(main_server_list, server) 62 | server_rows = consoleFn.rows_from_tuple(servers) 63 | header_row = ("{:<5}".format(txt.I_USE) + 64 | (server_rows[0].replace("|", " ").strip())) 65 | del server_rows[0] 66 | # setup form 67 | mainform = npyscreen.Form(name=self.title) 68 | mainform.add(npyscreen.TitleFixedText, name=txt.I_LIST_TITLE) 69 | mainform.add(npyscreen.TitleFixedText, name=header_row) 70 | selected_servers = mainform.add(npyscreen.MultiSelect, 71 | max_height=0, 72 | name=txt.I_LIST_TITLE, 73 | value=[], 74 | values=server_rows, 75 | scroll_exit=True) 76 | 77 | mainform.edit() # activate form 78 | self.done(selected_servers.get_selected_objects()) # done 79 | 80 | def done(self, selection): 81 | """After editing 82 | :param selection: 83 | """ 84 | if selection: 85 | for mirror in selection: 86 | server = mirror.split("|") 87 | self.custom_list.append({"country": server[0].strip(), 88 | "response_time": server[1].strip(), 89 | "last_sync": server[2].strip(), 90 | "url": server[3].strip()}) 91 | self.is_done = True 92 | self.setNextForm(None) 93 | 94 | 95 | def run(server_list, random, default): 96 | """Run""" 97 | app = ConsoleUI(server_list, random, default) 98 | app.run() 99 | return app 100 | -------------------------------------------------------------------------------- /pacman_mirrors/dialogs/graphicalui.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # 3 | # This file is part of pacman-mirrors. 4 | # 5 | # pacman-mirrors is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation, either version 3 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # pacman-mirrors is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with pacman-mirrors. If not, see . 17 | # 18 | # Authors: Esclapion 19 | # Hugo Posnic 20 | 21 | """Pacman-Mirrors GTK GUI Module""" 22 | 23 | import gi 24 | 25 | gi.require_version("Gtk", "3.0") 26 | from gi.repository import Gtk 27 | from operator import itemgetter 28 | from random import shuffle 29 | 30 | from pacman_mirrors.constants import txt 31 | from pacman_mirrors.translation import i18n 32 | 33 | _ = i18n.language.gettext 34 | 35 | 36 | class GraphicalUI(Gtk.Window): 37 | """Class GraphicalUI""" 38 | 39 | def __init__(self, server_list, random, default): 40 | title = txt.I_TITLE_RANDOM if random else txt.I_TITLE 41 | if default: 42 | title = "Manjaro Mirrors" 43 | Gtk.Window.__init__(self, title=title) 44 | self.random = random 45 | self.set_size_request(700, 350) 46 | self.set_border_width(10) 47 | self.set_position(Gtk.WindowPosition.CENTER) 48 | 49 | custom_mirrors = [] 50 | for server in server_list: 51 | try: 52 | _ = server_list[0] 53 | custom_mirrors.append( 54 | (False, server["country"], server["last_sync"], server["url"])) 55 | except IndexError as i: 56 | print("{} IndexError -> {}".format(txt.ERR_CLR, i)) 57 | pass 58 | except KeyError as k: 59 | print("{} KeyError -> {}".format(txt.ERR_CLR, k)) 60 | pass 61 | 62 | self.store = Gtk.ListStore(bool, str, str, str) 63 | for mirror_ref in custom_mirrors: 64 | self.store.append(list(mirror_ref)) 65 | 66 | scrolled_tree = Gtk.ScrolledWindow() 67 | 68 | self.tree = Gtk.TreeView(self.store, vexpand=True) 69 | 70 | renderer = Gtk.CellRendererToggle() 71 | renderer.connect("toggled", self.on_toggle) 72 | 73 | column = Gtk.TreeViewColumn(txt.I_USE, renderer, active=0) 74 | 75 | self.tree.append_column(column) 76 | 77 | renderer = Gtk.CellRendererText() 78 | column = Gtk.TreeViewColumn(txt.I_COUNTRY, renderer, text=1) 79 | column.set_sort_column_id(1) 80 | self.tree.append_column(column) 81 | 82 | renderer = Gtk.CellRendererText() 83 | column = Gtk.TreeViewColumn(txt.I_LAST_SYNC, 84 | renderer, 85 | text=2) 86 | column.set_sort_column_id(2) 87 | self.tree.append_column(column) 88 | 89 | renderer = Gtk.CellRendererText() 90 | column = Gtk.TreeViewColumn(txt.I_URL, 91 | renderer, 92 | text=3) 93 | column.set_sort_column_id(3) 94 | self.tree.append_column(column) 95 | 96 | scrolled_tree.add(self.tree) 97 | 98 | header = Gtk.Label(txt.I_LIST_TITLE) 99 | button_cancel = Gtk.Button(txt.I_CANCEL) 100 | button_cancel.connect("clicked", self.cancel) 101 | self.button_done = Gtk.Button(txt.I_CONFIRM, 102 | sensitive=False) 103 | self.button_done.connect("clicked", self.done) 104 | 105 | grid = Gtk.Grid(column_homogeneous=True, 106 | column_spacing=10, 107 | row_spacing=10) 108 | grid.attach(header, 0, 0, 2, 1) 109 | grid.attach(scrolled_tree, 0, 1, 2, 1) 110 | grid.attach(button_cancel, 0, 2, 1, 1) 111 | grid.attach(self.button_done, 1, 2, 1, 1) 112 | 113 | self.add(grid) 114 | 115 | # Server lists 116 | self.server_list = server_list 117 | self.custom_list = [] 118 | 119 | self.is_done = False 120 | 121 | def on_toggle(self, widget, path): 122 | """Add or remove server from custom list""" 123 | self.store[path][0] = not self.store[path][0] 124 | if self.store[path][0]: 125 | for server in self.server_list: 126 | if server["url"] == self.store[path][3]: 127 | self.custom_list.append(server) 128 | else: 129 | for server in self.custom_list: 130 | if server["url"] == self.store[path][3]: 131 | self.custom_list.remove(server) 132 | self.button_done.set_sensitive(bool(self.custom_list)) 133 | 134 | def cancel(self, button): 135 | """Cancel mirrorlist""" 136 | self.custom_list = [] 137 | self.is_done = True 138 | Gtk.main_quit() 139 | 140 | def done(self, button): 141 | """Confirm choice""" 142 | dialog = Gtk.Dialog(txt.I_CONFIRM_SELECTION, None, 0, ( 143 | Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, 144 | Gtk.STOCK_OK, Gtk.ResponseType.OK)) 145 | dialog.set_transient_for(self) 146 | dialog.set_border_width(10) 147 | box = dialog.get_content_area() 148 | box.set_spacing(10) 149 | box.add(Gtk.Label(txt.I_USE_THESE_MIRRORS)) 150 | dialog.show_all() 151 | response = dialog.run() 152 | 153 | if response == Gtk.ResponseType.OK: 154 | # Quit GUI 155 | dialog.destroy() 156 | for line in self.custom_list: 157 | line["last_sync"] = line["last_sync"].replace(" ", ":").replace("h", "").replace("m", "") 158 | if self.random: 159 | shuffle(self.custom_list) 160 | else: 161 | self.custom_list.sort(key=itemgetter("resp_time")) 162 | self.is_done = True 163 | Gtk.main_quit() 164 | elif response == Gtk.ResponseType.CANCEL: 165 | dialog.destroy() # Go back to selection 166 | 167 | 168 | def run(server_list, random, default=False): 169 | """Run""" 170 | window = GraphicalUI(server_list, random, default) 171 | window.connect("delete-event", Gtk.main_quit) 172 | window.show_all() 173 | Gtk.main() 174 | return window 175 | -------------------------------------------------------------------------------- /pacman_mirrors/functions/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/manjaro/pacman-mirrors/b7a0945214e40a1320a75962a4509b354d46b81c/pacman_mirrors/functions/__init__.py -------------------------------------------------------------------------------- /pacman_mirrors/functions/configFn.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # 3 | # This file is part of pacman-mirrors. 4 | # 5 | # pacman-mirrors is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation, either version 3 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # pacman-mirrors is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with pacman-mirrors. If not, see . 17 | # 18 | # Authors: Frede Hundewadt 19 | 20 | """Pacman-Mirrors Configuration Functions""" 21 | 22 | import sys 23 | 24 | from pacman_mirrors.config import configuration as conf 25 | from pacman_mirrors.constants import txt 26 | 27 | 28 | def setup_config(): 29 | """Get config informations 30 | :returns: config, custom 31 | :rtype: tuple 32 | """ 33 | custom = False 34 | # default config 35 | config = { 36 | "branch": "stable", 37 | "branches": conf.BRANCHES, 38 | "config_file": conf.CONFIG_FILE, 39 | "country_pool": [], 40 | "custom_file": conf.CUSTOM_FILE, 41 | "method": "rank", 42 | "work_dir": conf.WORK_DIR, 43 | "mirror_file": conf.MIRROR_FILE, 44 | "mirror_list": conf.MIRROR_LIST, 45 | "no_update": False, 46 | "protocols": [], 47 | "repo_arch": conf.REPO_ARCH, 48 | "ssl_verify": True, 49 | "status_file": conf.STATUS_FILE, 50 | "url_mirrors_json": conf.URL_MIRROR_JSON, 51 | "url_status_json": conf.URL_STATUS_JSON, 52 | "x32": False 53 | } 54 | # try to replace default entries by reading conf file 55 | try: 56 | with open(config["config_file"]) as conf_file: 57 | for line in conf_file: 58 | line = line.strip() 59 | if line.startswith("#") or "=" not in line: 60 | continue 61 | (key, value) = line.split("=", 1) 62 | key = key.rstrip() 63 | value = value.lstrip() 64 | if key and value: 65 | if value.startswith("\"") and value.endswith("\""): 66 | value = value[1:-1] 67 | if key == "Method": 68 | config["method"] = value 69 | if key == "Branch": 70 | config["branch"] = value 71 | if key == "Protocols": 72 | if "," in value: 73 | config["protocols"] = value.split(",") 74 | else: 75 | config["protocols"] = value.split(" ") 76 | if key == "SSLVerify": 77 | config["ssl_verify"] = value.lower().capitalize() 78 | 79 | except (PermissionError, OSError) as err: 80 | print(".: {} {}: {}: {}".format(txt.ERR_CLR, 81 | txt.CANNOT_READ_FILE, 82 | err.filename, 83 | err.strerror)) 84 | sys.exit(2) 85 | return config, custom 86 | 87 | 88 | def sanitize_config(config): 89 | """ 90 | Verify configuration 91 | :param config: 92 | """ 93 | errors = [] 94 | header = ".: {}: {} `{}`".format(txt.ERR_CLR, 95 | txt.INVALID_SETTING_IN, 96 | conf.CONFIG_FILE) 97 | # Check Method 98 | if config["method"] not in conf.METHODS: 99 | errors.append(" 'Method = {}'; {} {}".format( 100 | config["method"], txt.EXP_CLR, "|".join(conf.METHODS))) 101 | # Check Branch 102 | if config["x32"]: 103 | if config["branch"] not in conf.X32_BRANCHES: 104 | errors.append(" 'Branch = {}'; {} {}".format( 105 | config["branch"], txt.EXP_CLR, "|".join(conf.X32_BRANCHES))) 106 | else: 107 | if config["branch"] not in conf.BRANCHES: 108 | errors.append(" 'Branch = {}'; {} {}".format( 109 | config["branch"], txt.EXP_CLR, "|".join(conf.BRANCHES))) 110 | # Check SSLVerify 111 | if str(config["ssl_verify"]) not in conf.SSL: 112 | errors.append(" 'SSLVerify = {}'; {} {}".format( 113 | config["ssl_verify"], txt.EXP_CLR, "|".join(conf.SSL))) 114 | # Check Protocols 115 | for p in config["protocols"]: 116 | if p not in conf.PROTOCOLS: 117 | errors.append(" 'Protocols = {}'; {} {}".format( 118 | config["protocols"], txt.EXP_CLR, ",".join(conf.PROTOCOLS))) 119 | if len(errors): 120 | print(header) 121 | for e in errors: 122 | print(e) 123 | return False 124 | return True 125 | -------------------------------------------------------------------------------- /pacman_mirrors/functions/consoleFn.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # 3 | # This file is part of pacman-mirrors. 4 | # 5 | # pacman-mirrors is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation, either version 3 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # pacman-mirrors is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with pacman-mirrors. If not, see . 17 | # 18 | # Authors: Frede Hundewadt 19 | 20 | """Pacman-Mirrors Console UI Functions""" 21 | 22 | import json 23 | 24 | 25 | def list_to_tuple(list_data, named_tuple): 26 | """Comvert list to a list with named tuples 27 | :param list_data: the list to convert 28 | :param named_tuple: tuple list item converts to 29 | :return data: list of named tuples 30 | """ 31 | tdata = json.dumps(list_data) 32 | data = json.loads(tdata, object_hook=lambda x: named_tuple(**x)) 33 | return data 34 | 35 | 36 | def rows_from_tuple(servers, joiner=" | "): 37 | """Generates equal formatted lines 38 | :param servers: named tuples 39 | :param joiner: string used to join tuple items 40 | :return lines: list of nicely formatted lines 41 | """ 42 | rows = [] 43 | if servers: 44 | # calculate max col width 45 | col_width = [max(len(text) for text in col) for col in zip(*servers)] 46 | # generate linies 47 | for line in servers: 48 | rows.append(joiner.join("{:{}}".format(text, col_width[i]) 49 | for i, text in enumerate(line))) 50 | return rows 51 | -------------------------------------------------------------------------------- /pacman_mirrors/functions/convertFn.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # 3 | # This file is part of pacman-mirrors. 4 | # 5 | # pacman-mirrors is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation, either version 3 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # pacman-mirrors is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with pacman-mirrors. If not, see . 17 | # 18 | # Authors: Frede Hundewadt 19 | 20 | """Pacman-Mirrors Converter Functions""" 21 | 22 | from pacman_mirrors.constants import txt 23 | from pacman_mirrors.functions import util 24 | 25 | 26 | def translate_interactive_to_pool(interactive_pool, mirror_pool, config): 27 | """ 28 | Translate mirror pool for interactive display 29 | :param interactive_pool: 30 | :param mirror_pool: 31 | :param config: 32 | :return: 33 | """ 34 | custom_pool = [] 35 | mirror_list = [] 36 | custom_urls = set() 37 | custom_protocols = set() 38 | for custom in interactive_pool: 39 | try: 40 | """ 41 | url without protocol 42 | """ 43 | custom_url = util.get_server_location_from_url(custom["url"]) 44 | custom_protocol = util.get_protocol_from_url(custom["url"]) 45 | """ 46 | locate mirror in the full mirror pool 47 | """ 48 | for mirror in mirror_pool: 49 | try: 50 | _ = mirror_pool[0] 51 | mirror_url = util.get_server_location_from_url(mirror["url"]) 52 | if custom_url == mirror_url: 53 | if custom_url not in custom_urls: 54 | custom_urls.add(custom_url) 55 | custom_pool.append({ 56 | "country": mirror["country"], 57 | "protocols": mirror["protocols"], 58 | "url": mirror["url"] 59 | }) 60 | try: 61 | """ 62 | Try to replace protocols with user selection 63 | if selection exist 64 | """ 65 | _ = config["protocols"][0] 66 | mirror["protocols"] = config["protocols"] 67 | except IndexError: 68 | pass 69 | 70 | if custom_protocol not in custom_protocols: 71 | custom_protocols.add(custom_protocol) 72 | mirror_list.append({ 73 | "country": mirror["country"], 74 | "branches": mirror["branches"], 75 | "protocols": mirror["protocols"], 76 | "resp_time": mirror["resp_time"], 77 | "last_sync": mirror["last_sync"], 78 | "url": "{}{}".format(custom_protocol, mirror_url) 79 | }) 80 | 81 | except (KeyError, IndexError): 82 | print(".: {} {}! {}!".format(txt.WRN_CLR, txt.HOUSTON, txt.DEFAULT_POOL_EMPTY)) 83 | break 84 | custom_protocols = set() 85 | except KeyError: 86 | print(".: {} {}! {}!".format(txt.WRN_CLR, txt.HOUSTON, txt.CUSTOM_POOL_EMPTY)) 87 | break 88 | 89 | return custom_pool, mirror_list 90 | 91 | 92 | def translate_pool_to_interactive(mirror_pool): 93 | """ 94 | Translate mirror pool for interactive display 95 | :param mirror_pool: 96 | :return: list of dictionaries 97 | { 98 | "country": "country_name", 99 | "resp_time": "m.sss", 100 | "last_sync": "HHh MMm", 101 | "url": "http://server/repo/" 102 | } 103 | """ 104 | interactive_list = [] 105 | for mirror in mirror_pool: 106 | try: 107 | _ = mirror_pool[0] 108 | last_sync = str(mirror["last_sync"]).split(":") 109 | mirror_url = util.get_server_location_from_url(mirror["url"]) 110 | for idx, protocol in enumerate(mirror["protocols"]): 111 | interactive_list.append({ 112 | "country": mirror["country"], 113 | "resp_time": mirror["resp_time"], 114 | "last_sync": "{}h {}m".format(last_sync[0], last_sync[1]), 115 | "url": "{}{}".format(protocol, mirror_url) 116 | }) 117 | except (KeyError, IndexError): 118 | print(".: {} {}! {}!".format(txt.WRN_CLR, txt.HOUSTON, txt.MIRROR_POOL_EMPTY)) 119 | break 120 | return interactive_list 121 | 122 | 123 | -------------------------------------------------------------------------------- /pacman_mirrors/functions/countryFn.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # 3 | # This file is part of pacman-mirrors. 4 | # 5 | # pacman-mirrors is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation, either version 3 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # pacman-mirrors is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with pacman-mirrors. If not, see . 17 | # 18 | # Authors: Frede Hundewadt 19 | 20 | """Pacman-Mirrors Country Functions""" 21 | 22 | from pacman_mirrors.functions import httpFn 23 | from pacman_mirrors.functions import validFn 24 | 25 | 26 | def build_country_list(country_selection, country_pool, geoip=False): 27 | """ 28 | Do a check on the users country selection 29 | :param country_selection: 30 | :param country_pool: 31 | :param geoip: 32 | :return: list of valid countries 33 | :rtype: list 34 | """ 35 | """ 36 | Don't change this code 37 | This works so please don't touch 38 | """ 39 | result = [] 40 | if country_selection: 41 | if country_selection == ["all"]: 42 | result = country_pool 43 | else: 44 | if validFn.country_list_is_valid(country_selection, 45 | country_pool): 46 | result = country_selection 47 | if not result: 48 | if geoip: 49 | country = get_geoip_country(country_pool) 50 | if country: # valid geoip 51 | result = country 52 | else: 53 | result = country_pool 54 | else: 55 | result = country_pool 56 | return result 57 | 58 | 59 | def get_geoip_country(country_pool): 60 | """ 61 | Check if geoip is possible 62 | :param country_pool: 63 | :return: country name if found 64 | """ 65 | g_country = httpFn.get_geoip_country() 66 | if g_country in country_pool: 67 | return g_country 68 | else: 69 | return None 70 | 71 | 72 | -------------------------------------------------------------------------------- /pacman_mirrors/functions/customFn.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # 3 | # This file is part of pacman-mirrors. 4 | # 5 | # pacman-mirrors is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation, either version 3 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # pacman-mirrors is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with pacman-mirrors. If not, see . 17 | # 18 | # Authors: Frede Hundewadt 19 | 20 | """Pacman-Mirrors Custom Pool/Mirror Functions""" 21 | 22 | from pacman_mirrors.functions import defaultFn 23 | from pacman_mirrors.functions import fileFn 24 | from pacman_mirrors.functions import jsonFn 25 | from pacman_mirrors.functions import validFn 26 | 27 | 28 | def apply_status_to_custom_mirror_pool(config, custom_pool): 29 | """ 30 | Apply the current mirror status to the custom mirror file 31 | :param config: config dictionary 32 | :param custom_pool: the custom mirror pool 33 | :return: custom mirror pool with status applied 34 | """ 35 | status_list = tuple(jsonFn.read_json_file(config["status_file"], dictionary=False)) 36 | custom_list = tuple(custom_pool) 37 | try: 38 | _ = status_list[0] 39 | for custom in custom_list: 40 | for status in status_list: 41 | if custom["url"] in status["url"]: 42 | custom["last_sync"] = status["last_sync"] 43 | custom["branches"] = status["branches"] 44 | return list(custom_list) 45 | except (IndexError, KeyError): 46 | return custom_pool 47 | 48 | 49 | def check_custom_mirror_pool(self): 50 | """ 51 | Custom mirror pool or countries from CLI 52 | :return: True/False 53 | """ 54 | if validFn.custom_config_is_valid(): 55 | self.custom = True 56 | else: 57 | self.selected_countries = self.config["country_pool"] 58 | return self.custom 59 | 60 | 61 | def delete_custom_pool(self): 62 | """ 63 | Delete custom mirror pool 64 | """ 65 | self.custom = False 66 | self.config["country_pool"] = [] 67 | fileFn.delete_file(self.config["custom_file"]) 68 | 69 | 70 | def load_custom_mirror_pool(self): 71 | """ 72 | Load available custom mirrors and update their status from status.json 73 | If user request reset (--default) load the default pool 74 | """ 75 | if self.default: 76 | defaultFn.load_default_mirror_pool(self) 77 | else: 78 | defaultFn.seed_mirrors(self, self.config["custom_file"]) 79 | self.mirrors.mirror_pool = apply_status_to_custom_mirror_pool(self.config, self.mirrors.mirror_pool) 80 | 81 | -------------------------------------------------------------------------------- /pacman_mirrors/functions/defaultFn.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # 3 | # This file is part of pacman-mirrors. 4 | # 5 | # pacman-mirrors is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation, either version 3 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # pacman-mirrors is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with pacman-mirrors. If not, see . 17 | # 18 | # Authors: Frede Hundewadt 19 | 20 | """Pacman-Mirrors Default Pool/Mirror Functions""" 21 | 22 | from operator import itemgetter 23 | from pacman_mirrors.functions import countryFn 24 | from pacman_mirrors.functions import customFn 25 | from pacman_mirrors.functions import fileFn 26 | 27 | 28 | def load_config_mirror_pool(self): 29 | """ 30 | Load mirrors from active mirror pool 31 | """ 32 | if customFn.check_custom_mirror_pool(self) and not self.config["country_pool"]: 33 | customFn.load_custom_mirror_pool(self) 34 | self.selected_countries = self.mirrors.country_pool 35 | else: 36 | if self.config["country_pool"]: 37 | self.selected_countries = self.config["country_pool"] 38 | load_default_mirror_pool(self) 39 | """ 40 | Validate the list of selected countries 41 | """ 42 | self.selected_countries = countryFn.build_country_list(self.selected_countries, 43 | self.mirrors.country_pool, 44 | self.geoip) 45 | 46 | 47 | def load_default_mirror_pool(self): 48 | """ 49 | Load all available mirrors 50 | """ 51 | (file, status) = fileFn.return_mirror_filename(self.config) 52 | seed_mirrors(self, file, status) 53 | 54 | 55 | def seed_mirrors(self, file, status=False): 56 | """ 57 | Seed mirrors 58 | """ 59 | mirrors = fileFn.read_mirror_file(file) 60 | if status: 61 | self.mirrors.seed(mirrors, status=status) 62 | else: 63 | self.mirrors.seed(mirrors) 64 | sort_mirror_countries(self) 65 | 66 | 67 | def sort_mirror_countries(self): 68 | self.mirrors.mirror_pool = sorted(self.mirrors.mirror_pool, 69 | key=itemgetter("country")) 70 | self.mirrors.country_pool = sorted(self.mirrors.country_pool) 71 | 72 | -------------------------------------------------------------------------------- /pacman_mirrors/functions/fileFn.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # 3 | # This file is part of pacman-mirrors. 4 | # 5 | # pacman-mirrors is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation, either version 3 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # pacman-mirrors is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with pacman-mirrors. If not, see . 17 | # 18 | # Authors: Frede Hundewadt 19 | 20 | """Manjaro-Mirrors File Functions""" 21 | 22 | import datetime 23 | import os 24 | import sys 25 | 26 | import pacman_mirrors.functions.util 27 | from pacman_mirrors.constants import colors as color 28 | from pacman_mirrors.constants import txt 29 | from pacman_mirrors.functions import jsonFn 30 | 31 | 32 | def check_existance_of(filename, folder=False): 33 | """ 34 | Check existence of named file 35 | :param filename: 36 | :param folder: 37 | :returns bool if existing 38 | """ 39 | if folder: 40 | return os.path.isdir(filename) 41 | return os.path.isfile(filename) 42 | 43 | 44 | def create_dir(foldername): 45 | """ 46 | Create named folder if not exist 47 | :param foldername: 48 | """ 49 | os.makedirs(foldername, mode=0o755, exist_ok=True) 50 | 51 | 52 | def delete_file(filename): 53 | """ 54 | Delete the named file if exist 55 | :param filename: 56 | :return: 57 | """ 58 | if os.path.isfile(filename): 59 | os.remove(filename) 60 | 61 | 62 | def return_mirror_filename(config): 63 | """ 64 | Find the mirror pool file 65 | :param config: config dictionary 66 | :returns tuple with file and status 67 | """ 68 | filename = "" 69 | status = False # status.json or mirrors.json 70 | # decision on file availablity 71 | if check_existance_of(config["status_file"]): 72 | status = True 73 | filename = config["status_file"] 74 | elif check_existance_of(config["mirror_file"]): 75 | filename = config["mirror_file"] 76 | if not filename: 77 | print("\n{}.:! {}{}\n".format(color.RED, 78 | txt.HOUSTON, 79 | color.ENDCOLOR)) 80 | sys.exit(3) 81 | return filename, status 82 | 83 | 84 | def write_mirror_list(config, servers, custom=False, 85 | quiet=False, interactive=False): 86 | """ 87 | Write servers to /etc/pacman.d/mirrorlist 88 | :param config: configuration dictionary 89 | :param servers: list of servers to write 90 | :param custom: flag 91 | :param quiet: flag 92 | :param interactive: flag 93 | """ 94 | try: 95 | with open(config["mirror_list"], "w") as outfile: 96 | if not quiet: 97 | print(".: {} {}".format(txt.INF_CLR, txt.WRITING_MIRROR_LIST)) 98 | # write list header 99 | write_mirrorlist_header(outfile, custom=custom) 100 | cols, lines = pacman_mirrors.functions.util.terminal_size() 101 | for server in servers: 102 | if server["resp_time"] == "99.99": 103 | # do not write bad servers to mirrorlist 104 | continue 105 | if interactive: 106 | server["url"] = "{}{}{}".format(server["url"], 107 | config["branch"], 108 | config["repo_arch"]) 109 | if not quiet: 110 | message = " {:<15} : {}".format(server["country"], 111 | server["url"]) 112 | print("{:.{}}".format(message, cols)) 113 | else: 114 | url = server["url"] 115 | protocol = server["protocols"][0] 116 | pos = url.find(":") 117 | msg_url = server["url"] = "{}{}{}".format(protocol, 118 | url[pos:], 119 | config["branch"]) 120 | 121 | server["url"] = "{}{}{}{}".format(protocol, 122 | url[pos:], 123 | config["branch"], 124 | config["repo_arch"]) 125 | if not quiet: 126 | message = " {:<15} : {}".format(server["country"], 127 | msg_url) 128 | print("{:.{}}".format(message, cols)) 129 | 130 | # write list entry 131 | write_mirrorlist_entry(outfile, server) 132 | if not quiet: 133 | print(".: {} {}: {}".format(txt.INF_CLR, 134 | txt.MIRROR_LIST_SAVED, 135 | config["mirror_list"])) 136 | except OSError as err: 137 | print(".: {} {}: {}: {}".format(txt.ERR_CLR, 138 | txt.CANNOT_WRITE_FILE, 139 | err.filename, 140 | err.strerror)) 141 | sys.exit(2) 142 | 143 | 144 | def read_mirror_file(filename): 145 | """ 146 | Read content of named file - json data assumed 147 | :param filename: 148 | :returns: list of mirrors 149 | """ 150 | return jsonFn.read_json_file(filename, dictionary=True) 151 | 152 | 153 | def write_mirrorlist_header(handle, custom=False): 154 | """ 155 | Write mirrorlist header 156 | :param handle: handle to a file opened for writing 157 | :param custom: controls content of the header 158 | """ 159 | # handle creation time in unicode 160 | # http://stackoverflow.com/questions/16034060/ 161 | # python3-datetime-datetime-strftime-failed-to-accept-utf-8-string-format 162 | generated_timestamp = datetime.datetime.now().strftime("%Y-%m-%d %H:%M") 163 | handle.write("##\n") 164 | if custom: 165 | handle.write("## Manjaro Linux {}\n".format( 166 | txt.MIRROR_LIST_CUSTOM_HEADER)) 167 | handle.write("## {} {}\n".format( 168 | txt.MIRROR_LIST_GENERATED_ON, generated_timestamp)) 169 | handle.write("##\n") 170 | handle.write("## {} '{}' {}\n## {} '{}' {}\n## {} '{}'\n".format( 171 | txt.PLEASE_USE, txt.MODIFY_CUSTOM, txt.MIRROR_LIST_CUSTOM_RESET, 172 | txt.PLEASE_USE, txt.RESET_ALL, txt.MIRROR_LIST_CUSTOM_RESET, 173 | txt.REMOVE_CUSTOM_CONFIG, txt.RESET_ALL)) 174 | else: 175 | handle.write("## Manjaro Linux {}\n".format( 176 | txt.MIRROR_LIST_DEFAULT_HEADER)) 177 | handle.write("## {} {}\n".format( 178 | txt.MIRROR_LIST_GENERATED_ON, generated_timestamp)) 179 | handle.write("##\n") 180 | handle.write("## {} '{} {}' {}\n## ({})\n".format( 181 | txt.PLEASE_USE, txt.MODIFY_DEFAULT, txt.NUMBER, 182 | txt.MIRROR_LIST_DEFAULT_MODIFY, txt.USE_ZERO_FOR_ALL)) 183 | handle.write("##\n\n") 184 | 185 | 186 | def write_mirrorlist_entry(handle, mirror): 187 | """ 188 | Write mirror to mirror list or file 189 | :param handle: handle to a file opened for writing 190 | :param mirror: mirror object 191 | """ 192 | workitem = mirror 193 | handle.write("## Country : {}\n".format(workitem["country"])) 194 | handle.write("Server = {}\n\n".format(workitem["url"])) 195 | -------------------------------------------------------------------------------- /pacman_mirrors/functions/filterFn.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # 3 | # This file is part of pacman-mirrors. 4 | # 5 | # pacman-mirrors is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation, either version 3 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # pacman-mirrors is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with pacman-mirrors. If not, see . 17 | # 18 | # Authors: Frede Hundewadt 19 | 20 | """Pacman-Mirrors Filter Functions""" 21 | 22 | from pacman_mirrors.constants import txt 23 | from pacman_mirrors.config import configuration as conf 24 | 25 | 26 | def filter_bad_mirrors(mirror_pool): 27 | """ 28 | Remove known bad mirrors 29 | branch is == -1 30 | :param mirror_pool: the global mirror pool 31 | :return: list with bad mirrors removed 32 | """ 33 | result = [] 34 | for mirror in mirror_pool: 35 | if mirror["last_sync"] != txt.SERVER_BAD: 36 | result.append(mirror) 37 | return result 38 | 39 | 40 | def filter_mirror_country(mirror_pool, country_pool): 41 | """ 42 | Return new mirror pool with selected countries 43 | :param mirror_pool: 44 | :param country_pool: 45 | :rtype: list 46 | """ 47 | result = [] 48 | for mirror in mirror_pool: 49 | if mirror["country"] in country_pool: 50 | result.append(mirror) 51 | return result 52 | 53 | 54 | def filter_mirror_protocols(mirror_pool, protocols=None): 55 | """ 56 | Return a new mirrorlist with protocols 57 | :type mirror_pool: list 58 | :type protocols: list 59 | :rtype: list 60 | """ 61 | result = [] 62 | if not protocols: 63 | return mirror_pool 64 | for mirror in mirror_pool: 65 | accepted = [] 66 | for idx, protocol in enumerate(protocols): 67 | if protocol in mirror["protocols"]: 68 | accepted.append(protocol) 69 | if accepted: 70 | mirror["protocols"] = accepted 71 | result.append(mirror) 72 | return result 73 | 74 | 75 | def filter_poor_mirrors(mirror_pool, interval=9999): 76 | """ 77 | Remove poorly updated mirrors last_sync is more than interval hours 78 | :param mirror_pool: object 79 | :param interval: hours since last sync 80 | :return: list with mirrors removed which has not synced since interval 81 | """ 82 | result = [] 83 | for mirror in mirror_pool: 84 | last_sync = str(mirror["last_sync"]).split(":") 85 | if int(last_sync[0]) < interval: 86 | result.append(mirror) 87 | return result 88 | 89 | 90 | def filter_user_branch(mirror_pool, config): 91 | """ 92 | Filter mirrorlist on users branch and branch sync state 93 | """ 94 | for idx, branch in enumerate(conf.BRANCHES): 95 | if config["x32"]: 96 | config_branch = config["branch"][4:] 97 | else: 98 | config_branch = config["branch"] 99 | if branch == config_branch: 100 | filtered = [] 101 | for mirror in mirror_pool: 102 | try: 103 | if mirror["branches"][idx] == 1: 104 | filtered.append(mirror) 105 | except IndexError: 106 | pass 107 | if len(filtered) > 0: 108 | return filtered 109 | return mirror_pool 110 | 111 | 112 | -------------------------------------------------------------------------------- /pacman_mirrors/functions/jsonFn.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # 3 | # This file is part of pacman-mirrors. 4 | # 5 | # pacman-mirrors is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation, either version 3 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # pacman-mirrors is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with pacman-mirrors. If not, see . 17 | # 18 | # Authors: Frede Hundewadt 19 | 20 | """Pacman-Mirrors JSON Functions""" 21 | 22 | import collections 23 | import json 24 | 25 | 26 | def json_dump_file(data, filename): 27 | with open(filename, "w") as outfile: 28 | json.dump(data, outfile) 29 | 30 | 31 | def read_json_file(filename, dictionary=True): 32 | """Read json data from file""" 33 | result = list() 34 | try: 35 | if dictionary: 36 | with open(filename, "rb") as infile: 37 | result = json.loads( 38 | infile.read().decode("utf8"), 39 | object_pairs_hook=collections.OrderedDict) 40 | else: 41 | with open(filename, "r") as infile: 42 | result = json.load(infile) 43 | except OSError: 44 | pass 45 | return result 46 | 47 | 48 | def write_json_file(data, filename, dictionary=False): 49 | """Writes data to file as json 50 | :param data 51 | :param filename: 52 | :param dictionary: 53 | """ 54 | try: 55 | if dictionary: 56 | with open(filename, "wb") as outfile: 57 | json.dump(data, outfile) 58 | else: 59 | with open(filename, "w") as outfile: 60 | json.dump(data, outfile, sort_keys=True, indent=4) 61 | return True 62 | except OSError: 63 | return False 64 | -------------------------------------------------------------------------------- /pacman_mirrors/functions/outputFn.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # 3 | # This file is part of pacman-mirrors. 4 | # 5 | # pacman-mirrors is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation, either version 3 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # pacman-mirrors is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with pacman-mirrors. If not, see . 17 | # 18 | # Authors: Frede Hundewadt 19 | 20 | """Pacman-Mirrors Output Functions""" 21 | 22 | from pacman_mirrors.constants import txt 23 | from pacman_mirrors.functions import customFn 24 | from pacman_mirrors.functions import defaultFn 25 | from pacman_mirrors.functions import fileFn 26 | from pacman_mirrors.functions import jsonFn 27 | 28 | 29 | def console_custom_country_pool(self): 30 | """ 31 | List available countries from custom pool 32 | """ 33 | customFn.load_custom_mirror_pool(self) 34 | print("{}".format("\n".join(self.mirrors.country_pool))) 35 | 36 | 37 | def console_default_country_pool(self): 38 | """ 39 | List all available countries 40 | """ 41 | defaultFn.load_default_mirror_pool(self) 42 | print("{}".format("\n".join(self.mirrors.country_pool))) 43 | 44 | 45 | def file_custom_mirror_pool(self, selected_mirrors): 46 | """ 47 | Output selected mirrors to custom mirror file 48 | :param self: 49 | :param selected_mirrors: 50 | :return: 51 | """ 52 | print("\n.: {} {}".format(txt.INF_CLR, 53 | txt.CUSTOM_MIRROR_LIST)) 54 | print("--------------------------") 55 | # output mirror file 56 | jsonFn.write_json_file(selected_mirrors, 57 | self.config["custom_file"]) 58 | print(".: {} {}: {}".format(txt.INF_CLR, 59 | txt.CUSTOM_MIRROR_FILE_SAVED, 60 | self.config["custom_file"])) 61 | 62 | 63 | def file_mirror_list(self, selected_servers): 64 | """ 65 | Outputs selected servers to mirrorlist 66 | :param self: 67 | :param selected_servers: 68 | """ 69 | if self.custom: 70 | fileFn.write_mirror_list(self.config, 71 | selected_servers, 72 | custom=self.custom, 73 | quiet=self.quiet, 74 | interactive=True) 75 | else: 76 | fileFn.write_mirror_list(self.config, 77 | selected_servers, 78 | quiet=self.quiet) 79 | 80 | -------------------------------------------------------------------------------- /pacman_mirrors/functions/printFn.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # 3 | # This file is part of pacman-mirrors. 4 | # 5 | # pacman-mirrors is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation, either version 3 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # pacman-mirrors is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with pacman-mirrors. If not, see . 17 | # 18 | # Authors: Frede Hundewadt 19 | 20 | """Pacman-Mirrors Print Functions""" 21 | 22 | from pacman_mirrors.constants import colors as color 23 | 24 | 25 | def debug_msg(where, what, value): 26 | """Helper for printing debug messages""" 27 | print("{} {} >>>> '{} = {}'".format(color.DBG_CLR, where, what, value)) 28 | 29 | 30 | def blue_msg(message): 31 | """Helper for printing blue messages""" 32 | print("{}{}{}".format(color.BLUE, message, color.ENDCOLOR)) 33 | 34 | 35 | def green_msg(message): 36 | """Helper for printing green messages""" 37 | print("{}{}{}".format(color.GREEN, message, color.ENDCOLOR)) 38 | 39 | 40 | def red_msg(message): 41 | """Helper for printing yellow messages""" 42 | print("{}{}{}".format(color.RED, message, color.ENDCOLOR)) 43 | 44 | 45 | def yellow_msg(message): 46 | """Helper for printing yellow messages""" 47 | print("{}{}{}".format(color.YELLOW, message, color.ENDCOLOR)) 48 | 49 | 50 | -------------------------------------------------------------------------------- /pacman_mirrors/functions/testMirrorFn.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # 3 | # This file is part of pacman-mirrors. 4 | # 5 | # pacman-mirrors is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation, either version 3 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # pacman-mirrors is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with pacman-mirrors. If not, see . 17 | # 18 | # Authors: Frede Hundewadt 19 | 20 | """Pacman-Mirrors Test Mirror Functions""" 21 | 22 | import sys 23 | 24 | from pacman_mirrors.constants import txt, colors as color 25 | from pacman_mirrors.functions import httpFn 26 | from pacman_mirrors.functions import util 27 | 28 | 29 | def test_mirrors(self, worklist): 30 | """ 31 | Query server for response time 32 | """ 33 | if self.custom: 34 | print(".: {} {}".format(txt.INF_CLR, 35 | txt.USING_CUSTOM_FILE)) 36 | else: 37 | print(".: {} {}".format(txt.INF_CLR, 38 | txt.USING_DEFAULT_FILE)) 39 | print(".: {} {} - {}".format(txt.INF_CLR, 40 | txt.QUERY_MIRRORS, 41 | txt.TAKES_TIME)) 42 | cols, lines = util.terminal_size() 43 | # set connection timeouts 44 | http_wait = self.max_wait_time 45 | ssl_wait = self.max_wait_time * 2 46 | ssl_verify = self.config["ssl_verify"] 47 | for mirror in worklist: 48 | colon = mirror["url"].find(":") 49 | url = mirror["url"][colon:] 50 | for idx, proto in enumerate(mirror["protocols"]): 51 | mirror["url"] = "{}{}".format(proto, url) 52 | if not self.quiet: 53 | message = " ..... {:<15}: {}".format(mirror["country"], 54 | mirror["url"]) 55 | print("{:.{}}".format(message, cols), end="") 56 | sys.stdout.flush() 57 | # https sometimes takes longer for handshake 58 | if proto == "https" or proto == "ftps": 59 | self.max_wait_time = ssl_wait 60 | else: 61 | self.max_wait_time = http_wait 62 | # let's see how responsive you are 63 | mirror["resp_time"] = httpFn.get_mirror_response( 64 | mirror["url"], maxwait=self.max_wait_time, 65 | quiet=self.quiet, ssl_verify=ssl_verify) 66 | 67 | if float(mirror["resp_time"]) >= self.max_wait_time: 68 | if not self.quiet: 69 | print("\r") 70 | else: 71 | if not self.quiet: 72 | print("\r {:<5}{}{} ".format(color.GREEN, 73 | mirror["resp_time"], 74 | color.ENDCOLOR)) 75 | return worklist 76 | 77 | -------------------------------------------------------------------------------- /pacman_mirrors/functions/util.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # 3 | # This file is part of pacman-mirrors. 4 | # 5 | # pacman-mirrors is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation, either version 3 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # pacman-mirrors is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with pacman-mirrors. If not, see . 17 | # 18 | # Authors: Frede Hundewadt 19 | 20 | """Pacman-Mirrors Utility Functions""" 21 | 22 | 23 | import platform 24 | import shutil 25 | 26 | from pacman_mirrors.api import apifn 27 | from pacman_mirrors.constants import txt 28 | 29 | 30 | def extract_mirror_url(data): 31 | """Extract mirror url from data""" 32 | line = data.strip() 33 | if line.startswith("Server"): 34 | return line[9:].replace("$branch/$repo/$arch", "") 35 | 36 | 37 | def get_country(data): 38 | """Extract mirror country from data""" 39 | line = data.strip() 40 | if line.startswith("[") and line.endswith("]"): 41 | return line[1:-1] 42 | elif line.startswith("## Country") or line.startswith("## Location"): 43 | return line[19:] 44 | 45 | 46 | def get_protocol(data): 47 | """Extract protocol from url""" 48 | pos = data.find(":") 49 | return data[:pos] 50 | 51 | 52 | def get_protocol_from_url(url): 53 | """ 54 | Splits an url 55 | :param url: 56 | :returns protocol eg. http 57 | """ 58 | colon = url.find(":") 59 | if colon: 60 | return url[:colon] 61 | return url 62 | 63 | 64 | def get_server_location_from_url(url): 65 | """ 66 | Splits an url 67 | :param url: 68 | :returns url string without protocol 69 | """ 70 | colon = url.find(":") 71 | if colon: 72 | return url[colon:] 73 | return url 74 | 75 | 76 | def i686_check(self, write=False): 77 | if platform.machine() == "i686": 78 | self.config["x32"] = True 79 | if "x32" not in self.config["branch"]: 80 | self.config["branch"] = "x32-{}".format(self.config["branch"]) 81 | if write: 82 | apifn.write_config_branch(self.config["branch"], self.config["config_file"], quiet=True) 83 | 84 | 85 | def internet_message(): 86 | """Message when internet connection is down""" 87 | print(".: {} {}".format(txt.WRN_CLR, txt.INTERNET_DOWN)) 88 | print(".: {} {}".format(txt.INF_CLR, txt.MIRROR_RANKING_NA)) 89 | print(".: {} {}".format(txt.INF_CLR, txt.INTERNET_ALTERNATIVE)) 90 | 91 | 92 | def terminal_size(): 93 | """get terminal size""" 94 | # http://www.programcreek.com/python/example/85471/shutil.get_terminal_size 95 | cols = shutil.get_terminal_size().columns 96 | lines = shutil.get_terminal_size().lines 97 | result = (cols, lines) 98 | return result 99 | -------------------------------------------------------------------------------- /pacman_mirrors/functions/validFn.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # 3 | # This file is part of pacman-mirrors. 4 | # 5 | # pacman-mirrors is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation, either version 3 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # pacman-mirrors is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with pacman-mirrors. If not, see . 17 | # 18 | # Authors: Frede Hundewadt 19 | 20 | """Pacman-Mirrors Validation Functions""" 21 | 22 | import os 23 | import sys 24 | 25 | from pacman_mirrors.config import configuration as conf 26 | from pacman_mirrors.constants import txt 27 | 28 | 29 | def custom_config_is_valid(): 30 | """Check validity of custom selection 31 | :return: True or False 32 | :rtype: bool 33 | """ 34 | return os.path.isfile(conf.CUSTOM_FILE) 35 | # valid = os.path.isfile(conf.CUSTOM_FILE) 36 | # if not valid: 37 | # # validation fail - inform user and exit 38 | # print(".: {} {} {} {}".format(txt.ERR_CLR, 39 | # txt.CUSTOM_MIRROR_FILE, 40 | # conf.CUSTOM_FILE, 41 | # txt.DOES_NOT_EXIST)) 42 | # print(".: {} {}: {}".format(txt.INF_CLR, 43 | # txt.FALLING_BACK, 44 | # txt.USING_ALL_MIRRORS)) 45 | # return valid 46 | 47 | 48 | def country_list_is_valid(onlycountry, countrylist): 49 | """Check if the list of countries are valid. 50 | :param onlycountry: list of countries to check 51 | :param countrylist: list of available countries 52 | :return: True 53 | :rtype: bool 54 | """ 55 | for country in onlycountry: 56 | if country not in countrylist: 57 | print(".: {} {}{}: {}: '{}'".format(txt.WRN_CLR, 58 | txt.OPTION, 59 | txt.OPT_COUNTRY, 60 | txt.UNKNOWN_COUNTRY, 61 | country)) 62 | print(".: {} {}:".format(txt.INF_CLR, 63 | txt.AVAILABLE_COUNTRIES)) 64 | print("{}".format(", ".join(countrylist))) 65 | sys.exit(1) # exit gracefully 66 | return True 67 | -------------------------------------------------------------------------------- /pacman_mirrors/mirrors/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/manjaro/pacman-mirrors/b7a0945214e40a1320a75962a4509b354d46b81c/pacman_mirrors/mirrors/__init__.py -------------------------------------------------------------------------------- /pacman_mirrors/mirrors/mirror.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # 3 | # This file is part of pacman-mirrors. 4 | # 5 | # pacman-mirrors is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation, either version 3 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # pacman-mirrors is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with pacman-mirrors. If not, see . 17 | # 18 | # Authors: Frede Hundewadt 19 | 20 | 21 | """Pacman-Mirrors Mirror Class Module""" 22 | 23 | from pacman_mirrors.constants import txt 24 | 25 | 26 | class Mirror: 27 | """Mirror Class""" 28 | 29 | def __init__(self): 30 | self.country_pool = [] 31 | self.mirror_pool = [] 32 | 33 | def add(self, country, url, protocols, 34 | branches=None, last_sync=None, resp_time=None): 35 | """Append mirror 36 | :param country: 37 | :param url: 38 | :param protocols: 39 | :param branches: optional from status.json 40 | :param last_sync: optional from status.json 41 | :param resp_time: optional from status.json 42 | """ 43 | if last_sync is None: 44 | last_sync = "00:00" 45 | if resp_time is None: 46 | resp_time = "00.00" 47 | if branches is None: 48 | branches = [-1, -1, -1] 49 | if country not in self.country_pool: 50 | self.country_pool.append(country) 51 | # translate negative integer in status.json 52 | if last_sync == -1: 53 | last_sync = txt.SERVER_BAD 54 | resp_time = txt.SERVER_RES 55 | # sort protocols in reversed order https,http,ftps,ftp 56 | protocols = sorted(protocols, reverse=True) 57 | mirror = { 58 | "branches": branches, 59 | "country": country, 60 | "last_sync": last_sync, 61 | "protocols": protocols, 62 | "resp_time": resp_time, 63 | "url": url 64 | } 65 | self.mirror_pool.append(mirror) 66 | 67 | def seed(self, servers, status=False, custom=False): 68 | """ 69 | Seed mirrorlist 70 | :param servers: 71 | :param status: 72 | :param custom: 73 | """ 74 | if custom: # clear previous data 75 | self.country_pool = [] 76 | self.mirror_pool = [] 77 | for server in servers: 78 | if status: 79 | self.add(server["country"], 80 | server["url"], 81 | server["protocols"], 82 | server["branches"], 83 | server["last_sync"]) 84 | else: 85 | self.add(server["country"], 86 | server["url"], 87 | server["protocols"]) 88 | -------------------------------------------------------------------------------- /pacman_mirrors/pacman_mirrors.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # 3 | # This file is part of pacman-mirrors. 4 | # 5 | # pacman-mirrors is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation, either version 3 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # pacman-mirrors is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with pacman-mirrors. If not, see . 17 | # 18 | # Authors: Esclapion 19 | # philm 20 | # Ramon Buldó 21 | # Hugo Posnic 22 | # Frede Hundewadt 23 | 24 | """Pacman-Mirrors Main Module""" 25 | 26 | import importlib.util 27 | import sys 28 | 29 | import pacman_mirrors.functions.util 30 | from pacman_mirrors.builder import common, fasttrack, interactive 31 | from pacman_mirrors.config import configuration as conf 32 | from pacman_mirrors.functions import cliFn 33 | from pacman_mirrors.functions import configFn 34 | from pacman_mirrors.functions import defaultFn 35 | from pacman_mirrors.functions import fileFn 36 | from pacman_mirrors.functions import httpFn 37 | 38 | from pacman_mirrors.functions import util 39 | from pacman_mirrors.mirrors.mirror import Mirror 40 | from pacman_mirrors.translation import i18n 41 | 42 | try: 43 | importlib.util.find_spec("gi.repository.Gtk") 44 | except ImportError: 45 | GTK_AVAILABLE = False 46 | else: 47 | GTK_AVAILABLE = True 48 | _ = i18n.language.gettext 49 | 50 | 51 | class PacmanMirrors: 52 | """Class PacmanMirrors""" 53 | 54 | def __init__(self): 55 | """Init""" 56 | self.config = { 57 | "config_file": conf.CONFIG_FILE 58 | } 59 | self.custom = False 60 | self.default = False 61 | self.fasttrack = None 62 | self.geoip = False 63 | self.interactive = False 64 | self.max_wait_time = 2 65 | self.mirrors = Mirror() 66 | self.network = True 67 | self.no_display = False 68 | self.no_mirrorlist = False 69 | self.no_status = False 70 | self.quiet = False 71 | self.selected_countries = [] 72 | 73 | def run(self): 74 | """ 75 | Run 76 | # Setup config: retunrs the config dictionary and true/false on custom 77 | # Parse commandline 78 | # i686 check - change branch to x32-$branch 79 | # sanitize config 80 | # Check network 81 | # Update mirror pool 82 | # Check if mirrorlist is not to be touched - normal exit 83 | # Handle missing network 84 | # Load default mirror pool 85 | # Build mirror list 86 | """ 87 | (self.config, self.custom) = configFn.setup_config() 88 | fileFn.create_dir(self.config["work_dir"]) 89 | cliFn.parse_command_line(self, GTK_AVAILABLE) 90 | util.i686_check(self, write=True) 91 | if not configFn.sanitize_config(self.config): 92 | sys.exit(2) 93 | self.network = httpFn.inet_conn_check() 94 | if self.network: 95 | httpFn.update_mirror_pool(self.config, quiet=self.quiet) 96 | if self.no_mirrorlist: 97 | sys.exit(0) 98 | if not self.network: 99 | if not self.quiet: 100 | pacman_mirrors.functions.util.internet_message() 101 | self.config["method"] = "random" 102 | self.fasttrack = False 103 | """ 104 | # Load configured mirror pool 105 | """ 106 | defaultFn.load_config_mirror_pool(self) 107 | """ 108 | # Decide which type of mirrorlist to create 109 | * Fasttrack 110 | * Interactive 111 | * Default 112 | """ 113 | if self.fasttrack: 114 | fasttrack.build_mirror_list(self, self.fasttrack) 115 | elif self.interactive: 116 | interactive.build_mirror_list(self) 117 | else: 118 | common.build_mirror_list(self) 119 | 120 | 121 | if __name__ == "__main__": 122 | app = PacmanMirrors() 123 | app.run() 124 | 125 | -------------------------------------------------------------------------------- /pacman_mirrors/translation/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/manjaro/pacman-mirrors/b7a0945214e40a1320a75962a4509b354d46b81c/pacman_mirrors/translation/__init__.py -------------------------------------------------------------------------------- /pacman_mirrors/translation/custom_help_formatter.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # 3 | # This file is part of pacman-mirrors. 4 | # 5 | # pacman-mirrors is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation, either version 3 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # pacman-mirrors is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with pacman-mirrors. If not, see . 17 | # 18 | 19 | import argparse 20 | 21 | 22 | class CustomHelpFormatter(argparse.HelpFormatter): 23 | """Provide a customized format for help output. 24 | http://stackoverflow.com/questions/9642692/argparse-help-without-duplicate-allcaps 25 | https://github.com/Ecogenomics/mingle/blob/master/mingle/custom_help_formatter.py 26 | """ 27 | 28 | def _format_action_invocation(self, action): 29 | """Removes duplicate ALLCAPS with positional arguments.""" 30 | if not action.option_strings: 31 | default = self._get_default_metavar_for_positional(action) 32 | metavar, = self._metavar_formatter(action, default)(1) 33 | return metavar 34 | else: 35 | parts = [] 36 | # if the Optional doesn't take a value, format is: 37 | # -s, --long 38 | if action.nargs == 0: 39 | parts.extend(action.option_strings) 40 | # if the Optional takes a value, format is: 41 | # -s ARGS, --long ARGS 42 | else: 43 | default = self._get_default_metavar_for_optional(action) 44 | args_string = self._format_args(action, default) 45 | for option_string in action.option_strings: 46 | parts.append(option_string) 47 | 48 | return "%s %s" % (", ".join(parts), args_string) 49 | return ", ".join(parts) 50 | -------------------------------------------------------------------------------- /pacman_mirrors/translation/i18n.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # 3 | # This file is part of pacman-mirrors. 4 | # 5 | # pacman-mirrors is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation, either version 3 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # pacman-mirrors is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with pacman-mirrors. If not, see . 17 | # 18 | # from https://wiki.maemo.org/Internationalize_a_Python_application 19 | 20 | """Pacman-Mirrors Translation Module""" 21 | 22 | import os 23 | import sys 24 | import locale 25 | import gettext 26 | 27 | # The translation files will be under 28 | # @LOCALE_DIR@/@LANGUAGE@/LC_MESSAGES/@APP_NAME@.mo 29 | APP_NAME = "pacman_mirrors" 30 | 31 | APP_DIR = os.path.join(sys.prefix, "share") 32 | LOCALE_DIR = os.path.join(APP_DIR, "locale") 33 | 34 | # Now we need to choose the language. We will provide a list, and gettext 35 | # will use the first translation available in the list 36 | LANGUAGES = [] 37 | try: 38 | user_locale = locale.getdefaultlocale()[0] 39 | if user_locale: 40 | LANGUAGES += user_locale 41 | except ValueError: 42 | pass 43 | LANGUAGES += os.environ.get("LANG", "").split(":") 44 | LANGUAGES += ["en_US"] 45 | 46 | # Lets tell those details to gettext 47 | # (nothing to change here for you) 48 | gettext.install(True) 49 | gettext.bindtextdomain(APP_NAME, LOCALE_DIR) 50 | gettext.textdomain(APP_NAME) 51 | language = gettext.translation(APP_NAME, LOCALE_DIR, LANGUAGES, fallback=True) 52 | 53 | # Add this to every module: 54 | # 55 | # import i18n 56 | # _ = i18n.language.gettext 57 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/manjaro/pacman-mirrors/b7a0945214e40a1320a75962a4509b354d46b81c/requirements.txt -------------------------------------------------------------------------------- /scripts/pacman-mirrors: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # 3 | # This file is part of pacman_mirrors. 4 | # 5 | # pacman_mirrors is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation, either version 3 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # pacman_mirrors is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with pacman_mirrors. If not, see . 17 | # 18 | # Author(s): Ramon Buldó 19 | 20 | from pacman_mirrors import pacman_mirrors 21 | from pacman_mirrors.translation import i18n 22 | 23 | _ = i18n.language.gettext 24 | 25 | 26 | try: 27 | pm = pacman_mirrors.PacmanMirrors() 28 | pm.run() 29 | 30 | except KeyboardInterrupt: 31 | print("\n" + _("Error: interrupted by the user.")) 32 | exit(1) 33 | -------------------------------------------------------------------------------- /setup.cfg: -------------------------------------------------------------------------------- 1 | [wheel] 2 | universal = 1 3 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | #!/bin/env python 2 | 3 | import collections 4 | import io 5 | import json 6 | import re 7 | import os 8 | from urllib.request import urlopen 9 | from http.client import HTTPException 10 | from socket import timeout 11 | from urllib.error import URLError 12 | 13 | from setuptools import setup 14 | 15 | 16 | def update_mirror_file(): 17 | """update mirrors.json from github""" 18 | countries = list() 19 | try: 20 | with urlopen("https://github.com/manjaro/manjaro-web-repo/raw/master/mirrors.json") as response: 21 | countries = json.loads(response.read().decode("utf8"), object_pairs_hook=collections.OrderedDict) 22 | except (HTTPException, json.JSONDecodeError, URLError, timeout): 23 | pass 24 | if countries: 25 | with open("share/mirrors.json", "w") as outfile: 26 | json.dump(countries, outfile, sort_keys=True, indent=4) 27 | 28 | 29 | def read(*names, **kwargs): 30 | """read""" 31 | with io.open( 32 | os.path.join(os.path.dirname(__file__), *names), 33 | encoding=kwargs.get("encoding", "utf8") 34 | ) as fp: 35 | return fp.read() 36 | 37 | 38 | def find_version(*file_paths): 39 | """find version""" 40 | version_file = read(*file_paths) 41 | version_match = re.search(r"^__version__ = ['\"]([^'\"]*)['\"]", 42 | version_file, re.M) 43 | if version_match: 44 | return version_match.group(1) 45 | raise RuntimeError("Unable to find version string.") 46 | 47 | 48 | with open('README.md') as readme_file: 49 | README = readme_file.read() 50 | 51 | with open('CHANGELOG.md') as changelog_file: 52 | CHANGELOG = changelog_file.read() 53 | 54 | requirements = [ 55 | # TODO: put package requirements here 56 | ] 57 | 58 | test_requirements = [ 59 | # TODO: put package test requirements here 60 | ] 61 | 62 | update_mirror_file() 63 | 64 | setup( 65 | name='pacman-mirrors', 66 | version=find_version("pacman_mirrors", "__init__.py"), 67 | description="Package that provides all mirrors for Manjaro Linux.", 68 | long_description=README + '\n\n' + CHANGELOG, 69 | author="Roland Singer, Esclapion, Philip Müller, Ramon Buldó, Hugo Posnic, Frede Hundewadt", 70 | author_email='fh@manjaro.org', 71 | url='https://github.com/manjaro/pacman-mirrors', 72 | packages=['pacman_mirrors', 73 | 'pacman_mirrors.api', 74 | 'pacman_mirrors.builder', 75 | 'pacman_mirrors.config', 76 | 'pacman_mirrors.constants', 77 | 'pacman_mirrors.dialogs', 78 | 'pacman_mirrors.functions', 79 | 'pacman_mirrors.mirrors', 80 | 'pacman_mirrors.translation'], 81 | package_dir={'pacman_mirrors': 'pacman_mirrors'}, 82 | data_files=[('/etc', ['conf/pacman-mirrors.conf']), 83 | ('/etc/pacman.d', []), 84 | ('share/man/man8', ['man/pacman-mirrors.8.gz']), 85 | ('share/pacman-mirrors', ['share/mirrors.json']), 86 | ('share/locale/be/LC_MES SAGES', ['locale/be/LC_MESSAGES/pacman_mirrors.mo']), 87 | ('share/locale/bg/LC_MESSAGES', ['locale/bg/LC_MESSAGES/pacman_mirrors.mo']), 88 | ('share/locale/ca/LC_MESSAGES', ['locale/ca/LC_MESSAGES/pacman_mirrors.mo']), 89 | ('share/locale/cs/LC_MESSAGES', ['locale/cs/LC_MESSAGES/pacman_mirrors.mo']), 90 | ('share/locale/cy/LC_MESSAGES', ['locale/cy/LC_MESSAGES/pacman_mirrors.mo']), 91 | ('share/locale/da/LC_MESSAGES', ['locale/da/LC_MESSAGES/pacman_mirrors.mo']), 92 | ('share/locale/de/LC_MESSAGES', ['locale/de/LC_MESSAGES/pacman_mirrors.mo']), 93 | ('share/locale/el/LC_MESSAGES', ['locale/el/LC_MESSAGES/pacman_mirrors.mo']), 94 | ('share/locale/es/LC_MESSAGES', ['locale/es/LC_MESSAGES/pacman_mirrors.mo']), 95 | ('share/locale/es_419/LC_MESSAGES', ['locale/es_419/LC_MESSAGES/pacman_mirrors.mo']), 96 | ('share/locale/es_ES/LC_MESSAGES', ['locale/es_ES/LC_MESSAGES/pacman_mirrors.mo']), 97 | ('share/locale/fr/LC_MESSAGES', ['locale/fr/LC_MESSAGES/pacman_mirrors.mo']), 98 | ('share/locale/he/LC_MESSAGES', ['locale/he/LC_MESSAGES/pacman_mirrors.mo']), 99 | ('share/locale/hr/LC_MESSAGES', ['locale/hr/LC_MESSAGES/pacman_mirrors.mo']), 100 | ('share/locale/hr_HR/LC_MESSAGES', ['locale/hr_HR/LC_MESSAGES/pacman_mirrors.mo']), 101 | ('share/locale/hu/LC_MESSAGES', ['locale/hu/LC_MESSAGES/pacman_mirrors.mo']), 102 | ('share/locale/id_ID/LC_MESSAGES', ['locale/id_ID/LC_MESSAGES/pacman_mirrors.mo']), 103 | ('share/locale/is/LC_MESSAGES', ['locale/is/LC_MESSAGES/pacman_mirrors.mo']), 104 | ('share/locale/is_IS/LC_MESSAGES', ['locale/is_IS/LC_MESSAGES/pacman_mirrors.mo']), 105 | ('share/locale/it/LC_MESSAGES', ['locale/it/LC_MESSAGES/pacman_mirrors.mo']), 106 | ('share/locale/ja/LC_MESSAGES', ['locale/ja/LC_MESSAGES/pacman_mirrors.mo']), 107 | ('share/locale/lt/LC_MESSAGES', ['locale/lt/LC_MESSAGES/pacman_mirrors.mo']), 108 | ('share/locale/nb/LC_MESSAGES', ['locale/nb/LC_MESSAGES/pacman_mirrors.mo']), 109 | ('share/locale/nl/LC_MESSAGES', ['locale/nl/LC_MESSAGES/pacman_mirrors.mo']), 110 | ('share/locale/pl/LC_MESSAGES', ['locale/pl/LC_MESSAGES/pacman_mirrors.mo']), 111 | ('share/locale/pt/LC_MESSAGES', ['locale/pt/LC_MESSAGES/pacman_mirrors.mo']), 112 | ('share/locale/pt_BR/LC_MESSAGES', ['locale/pt_BR/LC_MESSAGES/pacman_mirrors.mo']), 113 | ('share/locale/pt_PT/LC_MESSAGES', ['locale/pt_PT/LC_MESSAGES/pacman_mirrors.mo']), 114 | ('share/locale/ro/LC_MESSAGES', ['locale/ro/LC_MESSAGES/pacman_mirrors.mo']), 115 | ('share/locale/ru_RU/LC_MESSAGES', ['locale/ru_RU/LC_MESSAGES/pacman_mirrors.mo']), 116 | ('share/locale/sk/LC_MESSAGES', ['locale/sk/LC_MESSAGES/pacman_mirrors.mo']), 117 | ('share/locale/sv/LC_MESSAGES', ['locale/sv/LC_MESSAGES/pacman_mirrors.mo']), 118 | ('share/locale/tr/LC_MESSAGES', ['locale/tr/LC_MESSAGES/pacman_mirrors.mo']), 119 | ('share/locale/tr_TR/LC_MESSAGES', ['locale/tr_TR/LC_MESSAGES/pacman_mirrors.mo']), 120 | ('share/locale/uk/LC_MESSAGES', ['locale/uk/LC_MESSAGES/pacman_mirrors.mo']), 121 | ('share/locale/uk_UA/LC_MESSAGES', ['locale/uk_UA/LC_MESSAGES/pacman_mirrors.mo']), 122 | ('share/locale/zh_CN/LC_MESSAGES', ['locale/zh_CN/LC_MESSAGES/pacman_mirrors.mo']), 123 | ('share/locale/zh_TW/LC_MESSAGES', ['locale/zh_TW/LC_MESSAGES/pacman_mirrors.mo']), 124 | ], 125 | scripts=["scripts/pacman-mirrors"], 126 | install_requires=requirements, 127 | license="GPL3", 128 | zip_safe=False, 129 | keywords='pacman-mirrors', 130 | classifiers=[ 131 | 'Development Status :: 5 - Production/Stable', 132 | 'Intended Audience :: End User/Desktop', 133 | 'License :: OSI Approved :: GPL3 License', 134 | 'Natural Language :: English', 135 | 'Programming Language :: Python :: 3', 136 | 'Programming Language :: Python :: 3.4', 137 | 'Programming Language :: Python :: 3.5', 138 | 'Programming Language :: Python :: 3.6', 139 | 'Environment :: Console' 140 | ], 141 | test_suite='tests', 142 | tests_require=test_requirements 143 | ) 144 | -------------------------------------------------------------------------------- /site/404.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | pacman-mirrors 12 | 13 | 14 | 15 | 16 | 17 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 72 | 73 |
74 | 75 |
76 |
77 |

404

78 |

Page not found

79 |
80 |
81 | 82 | 83 |
84 | 85 |
86 |
87 |

Documentation built with MkDocs.

88 |
89 | 90 | 91 | 92 | 93 | 94 | 157 | 158 | 159 | 160 | 161 | -------------------------------------------------------------------------------- /site/css/highlight.css: -------------------------------------------------------------------------------- 1 | /* 2 | This is the GitHub theme for highlight.js 3 | 4 | github.com style (c) Vasily Polovnyov 5 | 6 | */ 7 | 8 | .hljs { 9 | display: block; 10 | overflow-x: auto; 11 | color: #333; 12 | -webkit-text-size-adjust: none; 13 | } 14 | 15 | .hljs-comment, 16 | .diff .hljs-header, 17 | .hljs-javadoc { 18 | color: #998; 19 | font-style: italic; 20 | } 21 | 22 | .hljs-keyword, 23 | .css .rule .hljs-keyword, 24 | .hljs-winutils, 25 | .nginx .hljs-title, 26 | .hljs-subst, 27 | .hljs-request, 28 | .hljs-status { 29 | color: #333; 30 | font-weight: bold; 31 | } 32 | 33 | .hljs-number, 34 | .hljs-hexcolor, 35 | .ruby .hljs-constant { 36 | color: #008080; 37 | } 38 | 39 | .hljs-string, 40 | .hljs-tag .hljs-value, 41 | .hljs-phpdoc, 42 | .hljs-dartdoc, 43 | .tex .hljs-formula { 44 | color: #d14; 45 | } 46 | 47 | .hljs-title, 48 | .hljs-id, 49 | .scss .hljs-preprocessor { 50 | color: #900; 51 | font-weight: bold; 52 | } 53 | 54 | .hljs-list .hljs-keyword, 55 | .hljs-subst { 56 | font-weight: normal; 57 | } 58 | 59 | .hljs-class .hljs-title, 60 | .hljs-type, 61 | .vhdl .hljs-literal, 62 | .tex .hljs-command { 63 | color: #458; 64 | font-weight: bold; 65 | } 66 | 67 | .hljs-tag, 68 | .hljs-tag .hljs-title, 69 | .hljs-rule .hljs-property, 70 | .django .hljs-tag .hljs-keyword { 71 | color: #000080; 72 | font-weight: normal; 73 | } 74 | 75 | .hljs-attribute, 76 | .hljs-variable, 77 | .lisp .hljs-body, 78 | .hljs-name { 79 | color: #008080; 80 | } 81 | 82 | .hljs-regexp { 83 | color: #009926; 84 | } 85 | 86 | .hljs-symbol, 87 | .ruby .hljs-symbol .hljs-string, 88 | .lisp .hljs-keyword, 89 | .clojure .hljs-keyword, 90 | .scheme .hljs-keyword, 91 | .tex .hljs-special, 92 | .hljs-prompt { 93 | color: #990073; 94 | } 95 | 96 | .hljs-built_in { 97 | color: #0086b3; 98 | } 99 | 100 | .hljs-preprocessor, 101 | .hljs-pragma, 102 | .hljs-pi, 103 | .hljs-doctype, 104 | .hljs-shebang, 105 | .hljs-cdata { 106 | color: #999; 107 | font-weight: bold; 108 | } 109 | 110 | .hljs-deletion { 111 | background: #fdd; 112 | } 113 | 114 | .hljs-addition { 115 | background: #dfd; 116 | } 117 | 118 | .diff .hljs-change { 119 | background: #0086b3; 120 | } 121 | 122 | .hljs-chunk { 123 | color: #aaa; 124 | } 125 | -------------------------------------------------------------------------------- /site/fonts/fontawesome-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/manjaro/pacman-mirrors/b7a0945214e40a1320a75962a4509b354d46b81c/site/fonts/fontawesome-webfont.eot -------------------------------------------------------------------------------- /site/fonts/fontawesome-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/manjaro/pacman-mirrors/b7a0945214e40a1320a75962a4509b354d46b81c/site/fonts/fontawesome-webfont.ttf -------------------------------------------------------------------------------- /site/fonts/fontawesome-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/manjaro/pacman-mirrors/b7a0945214e40a1320a75962a4509b354d46b81c/site/fonts/fontawesome-webfont.woff -------------------------------------------------------------------------------- /site/fonts/fontawesome-webfont.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/manjaro/pacman-mirrors/b7a0945214e40a1320a75962a4509b354d46b81c/site/fonts/fontawesome-webfont.woff2 -------------------------------------------------------------------------------- /site/fonts/glyphicons-halflings-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/manjaro/pacman-mirrors/b7a0945214e40a1320a75962a4509b354d46b81c/site/fonts/glyphicons-halflings-regular.eot -------------------------------------------------------------------------------- /site/fonts/glyphicons-halflings-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/manjaro/pacman-mirrors/b7a0945214e40a1320a75962a4509b354d46b81c/site/fonts/glyphicons-halflings-regular.ttf -------------------------------------------------------------------------------- /site/fonts/glyphicons-halflings-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/manjaro/pacman-mirrors/b7a0945214e40a1320a75962a4509b354d46b81c/site/fonts/glyphicons-halflings-regular.woff -------------------------------------------------------------------------------- /site/fonts/glyphicons-halflings-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/manjaro/pacman-mirrors/b7a0945214e40a1320a75962a4509b354d46b81c/site/fonts/glyphicons-halflings-regular.woff2 -------------------------------------------------------------------------------- /site/img/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/manjaro/pacman-mirrors/b7a0945214e40a1320a75962a4509b354d46b81c/site/img/favicon.ico -------------------------------------------------------------------------------- /site/img/grid.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/manjaro/pacman-mirrors/b7a0945214e40a1320a75962a4509b354d46b81c/site/img/grid.png -------------------------------------------------------------------------------- /site/installation/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | Installation - pacman-mirrors 12 | 13 | 14 | 15 | 16 | 17 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 82 | 83 |
84 |
89 |
90 | 91 |

Installation

92 |

At the command line:

93 |
$ easy_install pacman-mirrors
 94 | 
95 |

Or, if you have virtualenvwrapper installed::

96 |
$ mkvirtualenv pacman-mirrors
 97 | $ pip install pacman-mirrors
 98 | 
99 |
100 | 101 |
102 |
103 |

Documentation built with MkDocs.

104 |
105 | 106 | 107 | 108 | 109 | 110 | 173 | 174 | 175 | 176 | 177 | -------------------------------------------------------------------------------- /site/js/base.js: -------------------------------------------------------------------------------- 1 | function getSearchTerm() 2 | { 3 | var sPageURL = window.location.search.substring(1); 4 | var sURLVariables = sPageURL.split('&'); 5 | for (var i = 0; i < sURLVariables.length; i++) 6 | { 7 | var sParameterName = sURLVariables[i].split('='); 8 | if (sParameterName[0] == 'q') 9 | { 10 | return sParameterName[1]; 11 | } 12 | } 13 | } 14 | 15 | $(document).ready(function() { 16 | 17 | var search_term = getSearchTerm(), 18 | $search_modal = $('#mkdocs_search_modal'), 19 | $keyboard_modal = $('#mkdocs_keyboard_modal'); 20 | 21 | if(search_term){ 22 | $search_modal.modal(); 23 | } 24 | 25 | // make sure search input gets autofocus everytime modal opens. 26 | $search_modal.on('shown.bs.modal', function () { 27 | $search_modal.find('#mkdocs-search-query').focus(); 28 | }); 29 | 30 | // Keyboard navigation 31 | document.addEventListener("keydown", function(e) { 32 | if ($(e.target).is(':input')) return true; 33 | var key = e.which || e.keyCode || window.event && window.event.keyCode; 34 | var page; 35 | switch (key) { 36 | case 39: // right arrow 37 | page = $('[role="navigation"] a:contains(Next):first').prop('href'); 38 | break; 39 | case 37: // left arrow 40 | page = $('[role="navigation"] a:contains(Previous):first').prop('href'); 41 | break; 42 | case 83: // s 43 | e.preventDefault(); 44 | $keyboard_modal.modal('hide'); 45 | $search_modal.modal('show'); 46 | $search_modal.find('#mkdocs-search-query').focus(); 47 | break; 48 | case 191: // ? 49 | $keyboard_modal.modal('show'); 50 | break; 51 | default: break; 52 | } 53 | if (page) { 54 | $keyboard_modal.modal('hide'); 55 | window.location.href = page; 56 | } 57 | }); 58 | 59 | // Highlight.js 60 | hljs.initHighlightingOnLoad(); 61 | $('table').addClass('table table-striped table-hover'); 62 | 63 | // Improve the scrollspy behaviour when users click on a TOC item. 64 | $(".bs-sidenav a").on("click", function() { 65 | var clicked = this; 66 | setTimeout(function() { 67 | var active = $('.nav li.active a'); 68 | active = active[active.length - 1]; 69 | if (clicked !== active) { 70 | $(active).parent().removeClass("active"); 71 | $(clicked).parent().addClass("active"); 72 | } 73 | }, 50); 74 | }); 75 | 76 | }); 77 | 78 | 79 | $('body').scrollspy({ 80 | target: '.bs-sidebar', 81 | }); 82 | 83 | /* Toggle the `clicky` class on the body when clicking links to let us 84 | retrigger CSS animations. See ../css/base.css for more details. */ 85 | $('a').click(function(e) { 86 | $('body').toggleClass('clicky'); 87 | }); 88 | 89 | /* Prevent disabled links from causing a page reload */ 90 | $("li.disabled a").click(function() { 91 | event.preventDefault(); 92 | }); 93 | -------------------------------------------------------------------------------- /site/search/search-results-template.mustache: -------------------------------------------------------------------------------- 1 | 5 | -------------------------------------------------------------------------------- /site/search/search.js: -------------------------------------------------------------------------------- 1 | require.config({ 2 | baseUrl: base_url + "/search/" 3 | }); 4 | 5 | require([ 6 | 'mustache.min', 7 | 'lunr.min', 8 | 'text!search-results-template.mustache', 9 | 'text!search_index.json', 10 | ], function (Mustache, lunr, results_template, data) { 11 | "use strict"; 12 | 13 | function getSearchTerm() 14 | { 15 | var sPageURL = window.location.search.substring(1); 16 | var sURLVariables = sPageURL.split('&'); 17 | for (var i = 0; i < sURLVariables.length; i++) 18 | { 19 | var sParameterName = sURLVariables[i].split('='); 20 | if (sParameterName[0] == 'q') 21 | { 22 | return decodeURIComponent(sParameterName[1].replace(/\+/g, '%20')); 23 | } 24 | } 25 | } 26 | 27 | var index = lunr(function () { 28 | this.field('title', {boost: 10}); 29 | this.field('text'); 30 | this.ref('location'); 31 | }); 32 | 33 | data = JSON.parse(data); 34 | var documents = {}; 35 | 36 | for (var i=0; i < data.docs.length; i++){ 37 | var doc = data.docs[i]; 38 | doc.location = base_url + doc.location; 39 | index.add(doc); 40 | documents[doc.location] = doc; 41 | } 42 | 43 | var search = function(){ 44 | 45 | var query = document.getElementById('mkdocs-search-query').value; 46 | var search_results = document.getElementById("mkdocs-search-results"); 47 | while (search_results.firstChild) { 48 | search_results.removeChild(search_results.firstChild); 49 | } 50 | 51 | if(query === ''){ 52 | return; 53 | } 54 | 55 | var results = index.search(query); 56 | 57 | if (results.length > 0){ 58 | for (var i=0; i < results.length; i++){ 59 | var result = results[i]; 60 | doc = documents[result.ref]; 61 | doc.base_url = base_url; 62 | doc.summary = doc.text.substring(0, 200); 63 | var html = Mustache.to_html(results_template, doc); 64 | search_results.insertAdjacentHTML('beforeend', html); 65 | } 66 | } else { 67 | search_results.insertAdjacentHTML('beforeend', "

No results found

"); 68 | } 69 | 70 | if(jQuery){ 71 | /* 72 | * We currently only automatically hide bootstrap models. This 73 | * requires jQuery to work. 74 | */ 75 | jQuery('#mkdocs_search_modal a').click(function(){ 76 | jQuery('#mkdocs_search_modal').modal('hide'); 77 | }); 78 | } 79 | 80 | }; 81 | 82 | var search_input = document.getElementById('mkdocs-search-query'); 83 | 84 | var term = getSearchTerm(); 85 | if (term){ 86 | search_input.value = term; 87 | search(); 88 | } 89 | 90 | if (search_input){search_input.addEventListener("keyup", search);} 91 | 92 | }); 93 | -------------------------------------------------------------------------------- /site/sitemap.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | / 7 | 2018-04-01 8 | daily 9 | 10 | 11 | 12 | 13 | 14 | /installation/ 15 | 2018-04-01 16 | daily 17 | 18 | 19 | 20 | 21 | 22 | /usage/ 23 | 2018-04-01 24 | daily 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /site/usage/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | Usage - pacman-mirrors 12 | 13 | 14 | 15 | 16 | 17 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 82 | 83 |
84 |
89 |
90 | 91 |

Usage

92 |

To use pacman-mirrors in a Python project:

93 |
import pacman_mirrors
 94 | 
95 |
96 | 97 |
98 |
99 |

Documentation built with MkDocs.

100 |
101 | 102 | 103 | 104 | 105 | 106 | 169 | 170 | 171 | 172 | 173 | -------------------------------------------------------------------------------- /tests/.gitignore: -------------------------------------------------------------------------------- 1 | /test.sh 2 | -------------------------------------------------------------------------------- /tests/README.md: -------------------------------------------------------------------------------- 1 | Running test for the first time on a fresh install will generate errors. 2 | === 3 | 4 | The error can safely be ignored. 5 | 6 | test_geoip_available (tests.test_httpfn.TestHttpFn) 7 | TEST: Geoip country IS avaiable ... 8 | ::.:! Houston?! We have a problem. 9 | 10 | ERROR 11 | test_geoip_not_available (tests.test_httpfn.TestHttpFn) 12 | TEST: Geoip country IS NOT available ... 13 | ::.:! Houston?! We have a problem. 14 | 15 | ERROR 16 | 17 | The technical cause is a missing file in the folder 18 | 19 | tests/mock/usr/mirrors.json 20 | 21 | The test suite is run in alphabetic order so the will be downloaded later and is available on subsequent runs. 22 | -------------------------------------------------------------------------------- /tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/manjaro/pacman-mirrors/b7a0945214e40a1320a75962a4509b354d46b81c/tests/__init__.py -------------------------------------------------------------------------------- /tests/apitest.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | BRANCH=$( (pacman-mirrors --api --get-branch >&1) 2>&1 ) 4 | echo "branch is '${BRANCH}'" 5 | -------------------------------------------------------------------------------- /tests/mock/etc/.gitignore: -------------------------------------------------------------------------------- 1 | /mirrorlist 2 | -------------------------------------------------------------------------------- /tests/mock/etc/pacman-mirrors.conf: -------------------------------------------------------------------------------- 1 | ## 2 | ## /etc/pacman-mirrors.conf 3 | ## 4 | 5 | ## Branch Pacman should use (stable, testing, unstable) 6 | # Branch = stable 7 | 8 | ## Generation method 9 | ## 1) rank - rank mirrors depending on their access time 10 | ## 2) random - randomly generate the output mirrorlist 11 | # Method = rank 12 | 13 | ## Define protocols and priority 14 | ## separated by comma 'https,http' or 'http,https' 15 | ## ATM available protocols are: http, https, ftp 16 | ## Not specifying a protocol will ban the protocol from being used 17 | ## If a mirror has more than one protocol defined only the first is written to the mirrorlist 18 | ## Empty means all in reversed alphabetic order 19 | # Protocols = 20 | 21 | ## When set to False - all certificates are accepted. 22 | ## Use only if you fully trust all ssl-enabled mirrors. 23 | # SSLVerify = True 24 | -------------------------------------------------------------------------------- /tests/mock/etc/pacman.d/.gitignore: -------------------------------------------------------------------------------- 1 | /mirrorlist 2 | -------------------------------------------------------------------------------- /tests/mock/usr/.gitignore: -------------------------------------------------------------------------------- 1 | /mirrors.json 2 | -------------------------------------------------------------------------------- /tests/mock/usr/share/pacman-mirrors/.gitignore: -------------------------------------------------------------------------------- 1 | /mirrors.json 2 | -------------------------------------------------------------------------------- /tests/mock/var/.gitignore: -------------------------------------------------------------------------------- 1 | /status.json 2 | -------------------------------------------------------------------------------- /tests/mock_configuration.py: -------------------------------------------------------------------------------- 1 | # http constants 2 | URL_MIRROR_JSON = "http://repo.manjaro.org/mirrors.json" 3 | URL_STATUS_JSON = "http://repo.manjaro.org/status.json" 4 | # etc 5 | CONFIG_FILE = "tests/mock/etc/pacman-mirrors.conf" 6 | MIRROR_LIST = "tests/mock/etc/mirrorlist" 7 | # pacman-mirrors 8 | WORK_DIR = "tests/mock/var/" 9 | CUSTOM_FILE = "tests/mock/var/custom-mirrors.json" 10 | MIRROR_FILE = "tests/mock/usr/mirrors.json" 11 | STATUS_FILE = "tests/mock/var/status.json" 12 | # repo constants 13 | BRANCHES = ("stable", "testing", "unstable") 14 | X32_BRANCHES = ("x32-stable", "x32-testing", "x32-unstable") 15 | PROTOCOLS = ("https", "http", "ftp", "ftps") 16 | METHODS = ("rank", "random") 17 | SSL = ("True", "False") 18 | REPO_ARCH = "/$repo/$arch" 19 | # special cases 20 | O_CUST_FILE = "tests/mock/var/Custom" 21 | TO_BE_REMOVED = "tests/mock/var/mirrors.json" 22 | -------------------------------------------------------------------------------- /tests/test-checkpoints.md: -------------------------------------------------------------------------------- 1 | ## Pacman-Mirrors testpoints 2 | ### Geoip 3 | 4 | * `--geoip -b stable -o geoip-stable-mirrorlist.txt` 5 | - check `geoip-stable-mirrorlist.txt` Should contain mirrors/stable from geoip country 6 | - check `/etc/pacman-mirrors.conf` OnlyCountry should equal nothing 7 | 8 | * `--geoip -b testing -o geoip-testing-mirrorlist.txt` 9 | - check `geoip-testing-mirrorlist.txt` Should contain mirrors/testing from geoip country 10 | - check `/etc/pacman-mirrors.conf` OnlyCountry should equal nothing 11 | 12 | * `--geoip -b unstable -o geoip-unstable-mirrorlist.txt` 13 | - check `geoip-unstable-mirrorlist.txt` Should contain mirrors/unstable from geoip country 14 | - check `/etc/pacman-mirrors.conf` OnlyCountry should equal nothing 15 | 16 | ### Fasttrack 17 | 18 | * `-f 5 -b stable -o fasttrack-5-stable-mirrorlist.txt` 19 | - check `fasttrack-5-stable-mirrorlist.txt` Should contain 5 mirrors/stable - some hosts have several protocols 20 | - check `/etc/pacman-mirrors.conf` OnlyCountry should equal nothing 21 | 22 | * `-f 5 -b testing -o fasttrack-5-testing-mirrorlist.txt` 23 | - check `fasttrack-5-testing-mirrorlist.txt` Should contain 5 mirrors/testing - some hosts have several protocols 24 | - check `/etc/pacman-mirrors.conf` OnlyCountry should equal nothing 25 | 26 | * `-f 5 -b unstable -o fasttrack-5-unstable-mirrorlist.txt` 27 | - check `fasttrack-5-unstable-mirrorlist.txt` Should contain 5 mirrors/unstable - some hosts have several protocols 28 | - check `/etc/pacman-mirrors.conf` OnlyCountry should equal nothing 29 | 30 | * `-i -o fasttrack-only_country_is_custom.txt` 31 | - select 2 mirrors and save 32 | - check `pacman-mirrors.conf` should have `OnlyCountry = Custom` 33 | - run `-f 5 -o fasttrack-only_country_is_custom.txt` 34 | - check `fasttrack-only_country_is_custom.txt` should countain 5 mirrors 35 | - check `pacman-mirrors.con` should have `OnlyCountry = Custom` 36 | 37 | ### Default generation method = rank 38 | 39 | * `-g -b stable -o default-stable-mirrorlist.txt` 40 | * `default-stable-mirrorlist.txt` Should contain mirrors/stable ranked by response time 41 | 42 | * `-g -b testing -o default-testing-mirrorlist.txt` 43 | * `default-testing-mirrorlist.txt` Should contain mirrors/testing ranked by response time 44 | 45 | * `-g -b unstable -o default-unstable-mirrorlist.txt` 46 | * `default-unstable-mirrorlist.txt` Should contain mirrors/unstable ranked by response time 47 | 48 | ### Single country 49 | 50 | * `-c Germany -b stable -o germany-stable-mirrorlist.txt` 51 | - check `/etc/pacman-mirrors.conf` OnlyCountry should equal Germany 52 | - check `germany-stable-mirrorlist.txt` Should contain only mirrors/stable from Germany 53 | 54 | * `-c Germany -b testing -o germany-testing-mirrorlist.txt` 55 | - check `/etc/pacman-mirrors.conf` OnlyCountry should equal Germany 56 | - check `germany-testing-mirrorlist.txt` Should contain only mirrors/testing from Germany 57 | 58 | * `-c Germany -b unstable -o germany-unstable-mirrorlist.txt` 59 | - check `/etc/pacman-mirrors.conf` OnlyCountry should equal Germany 60 | - check `germany-unstable-mirrorlist.txt` Should contain only mirrors/unstable from Germany 61 | 62 | ### Single country method = random 63 | 64 | * `-c France -b stable -m random -o france-random-stable-mirrorlist.txt` 65 | - check `/etc/pacman-mirrors.conf` OnlyCountry should equal France 66 | - check `france-unstable-mirrorlist.txt` Should contain only, in random order, mirrors/unstable from France 67 | 68 | * `-c France -b testing -m random -o france-random-testing-mirrorlist.txt` 69 | - check `/etc/pacman-mirrors.conf` OnlyCountry should equal France 70 | - check `france-unstable-mirrorlist.txt` Should contain only, in random order, mirrors/testing from France 71 | 72 | * `-c France -b unstable -m random -o france-random-unstable-mirrorlist.txt` 73 | - check `/etc/pacman-mirrors.conf` OnlyCountry should equal France 74 | - check `france-unstable-mirrorlist.txt` Should contain only, in random order, mirrors/unstable from France 75 | 76 | ### Single country interactive 77 | 78 | * `-c Italy -i -b stable -o italy-interactive-mirrorlist.txt` 79 | - action: select all mirrors from the list 80 | - check `/var/lib/pacman-mirrors/custom-mirrors.json` Should be created 81 | - check `italy-interactive-mirrorlist.txt` Should contain mirrors/stable from Italy 82 | - check `/etc/pacman-mirrors.conf` OnlyCountry should equal Custom 83 | 84 | * `-c all -b stable -m random -o interactive-reset-mirrorlist.txt` 85 | - check `/var/lib/pacman-mirrors/custom-mirrors.json` Should be deleted 86 | - check `interactive-reset-mirrorlist` Should contain mirrors/stable in random order 87 | - check `/etc/pacman-mirrors.conf` OnlyCountry should equal nothing 88 | 89 | ### Single mirror interactive 90 | 91 | * `-c all -b stable -m random -o check-interactive-mirrorlist.txt` 92 | - action: select ONE mirror on the list 93 | - check `/var/lib/pacman-mirrors/custom-mirrors.json` Should be created 94 | - check `/var/lib/pacman-mirrors/custom-mirrors.json` Should contain one mirror 95 | - check `check-interactive-mirrorlist` Should contain exactly one mirror/stable - maybe several protocols 96 | - check `/etc/pacman-mirrors.conf` OnlyCountry should equal Custom 97 | -------------------------------------------------------------------------------- /tests/test-pacman-mirrors-output.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | sudo pacman-mirrors --geoip -b stable -o geoip-stable-mirrorlist.txt 3 | echo -e "\e[1m\e[41mResult was written to geoip-stable-mirrorlist.txt\e[m" 4 | echo Verify checkpoint... 5 | read -n 1 6 | sudo pacman-mirrors --geoip -b testing -o geoip-testing-mirrorlist.txt 7 | echo -e "\e[1m\e[41mResult was written to geoip-testing-mirrorlist.txt\e[m" 8 | echo Verify checkpoint... 9 | read -n 1 10 | sudo pacman-mirrors --geoip -b unstable -o geoip-unstable-mirrorlist.txt 11 | echo -e "\e[1m\e[41mResult was written to geoip-unstable-mirrorlist.txt\e[m" 12 | echo Verify checkpoint... 13 | read -n 1 14 | # 15 | sudo pacman-mirrors -f 5 -b stable -o fasttrack-5-stable-mirrorlist.txt 16 | echo -e "\e[1m\e[41mResult was written to fasttrack-5-stable-mirrorlist.txt\e[m" 17 | echo Verify checkpoint... 18 | read -n 1 19 | sudo pacman-mirrors -f 5 -b testing -o fasttrack-5-testing-mirrorlist.txt 20 | echo -e "\e[1m\e[41mResult was written to fasttrack-5-testing-mirrorlist.txt\e[m" 21 | echo Verify checkpoint... 22 | read -n 1 23 | sudo pacman-mirrors -f 5 -b unstable -o fasttrack-5-unstable-mirrorlist.txt 24 | echo -e "\e[1m\e[41mResult was written to fasttrack-5-unstable-mirrorlist.txt\e[m" 25 | echo Verify checkpoint... 26 | read -n 1 27 | sudo pacman-mirrors -i -o fasttrack-only_country_is_custom.txt 28 | echo -e "\e[1m\e[41mResult was written to fasttrack-only_country_is_custom.txt\e[m" 29 | echo Verify checkpoint... 30 | read -n 1 31 | sudo pacman-mirrors -f 5 -o fasttrack-only_country_is_custom.txt 32 | echo -e "\e[1m\e[41mResult was written to fasttrack-only_country_is_custom.txt\e[m" 33 | echo Verify checkpoint... 34 | read -n 1 35 | # 36 | sudo pacman-mirrors -g -b stable -o default-stable-mirrorlist.txt 37 | echo -e "\e[1m\e[41mResult was written to default-stable-mirrorlist.txt\e[m" 38 | echo Verify checkpoint... 39 | read -n 1 40 | sudo pacman-mirrors -g -b testing -o default-testing-mirrorlist.txt 41 | echo -e "\e[1m\e[41mResult was written to default-testing-mirrorlist.txt\e[m" 42 | echo Verify checkpoint... 43 | read -n 1 44 | sudo pacman-mirrors -g -b unstable -o default-unstable-mirrorlist.txt 45 | echo -e "\e[1m\e[41mResult was written to default-unstable-mirrorlist.txt\e[m" 46 | echo Verify checkpoint... 47 | read -n 1 48 | # 49 | sudo pacman-mirrors -c Germany -b stable -o germany-stable-mirrorlist.txt 50 | echo -e "\e[1m\e[41mResult was written to germany-stable-mirrorlist.txt\e[m" 51 | echo Verify checkpoint... 52 | read -n 1 53 | sudo pacman-mirrors -c Germany -b testing -o germany-testing-mirrorlist.txt 54 | echo -e "\e[1m\e[41mResult was written to germany-testing-mirrorlist.txt\e[m" 55 | echo Verify checkpoint... 56 | read -n 1 57 | sudo pacman-mirrors -c Germany -b unstable -o germany-unstable-mirrorlist.txt 58 | echo -e "\e[1m\e[41mResult was written to germany-unstable-mirrorlist.txt\e[m" 59 | echo Verify checkpoint... 60 | read -n 1 61 | # 62 | sudo pacman-mirrors -c France -b stable -m random -o france-random-stable-mirrorlist.txt 63 | echo -e "\e[1m\e[41mResult was written to france-random-stable-mirrorlist.txt\e[m" 64 | echo Verify checkpoint... 65 | read -n 1 66 | sudo pacman-mirrors -c France -b testing -m random -o france-random-testing-mirrorlist.txt 67 | echo -e "\e[1m\e[41mResult was written to france-random-testing-mirrorlist.txt\e[m" 68 | echo Verify checkpoint... 69 | read -n 1 70 | sudo pacman-mirrors -c France -b unstable -m random -o france-random-unstable-mirrorlist.txt 71 | echo -e "\e[1m\e[41mResult was written to france-random-unstable-mirrorlist.txt\e[m" 72 | echo Verify checkpoint... 73 | read -n 1 74 | # 75 | sudo pacman-mirrors -i -c Italy -b stable -o italy-interactive-mirrorlist.txt 76 | echo -e "\e[1m\e[41mResult was written to italy-interactive-mirrorlist.txt\e[m" 77 | echo Verify checkpoint... 78 | read -n 1 79 | sudo pacman-mirrors -c all -b stable -m random -o interactive-reset-mirrorlist.txt 80 | echo -e "\e[1m\e[41mResult was written to interactive-reset-mirrorlist.txt\e[m" 81 | echo Verify checkpoint... 82 | read -n 1 83 | sudo pacman-mirrors -i -c all -m random -o check-interactive-mirrorlist.txt 84 | echo -e "\e[1m\e[41mResult was written to check-len-interactive-mirrorlist.txt\e[m" 85 | echo Verify checkpoint... 86 | read -n 1 87 | 88 | sudo chmod 0777 *-mirrorlist.txt 89 | 90 | -------------------------------------------------------------------------------- /tests/test_command_line_parse.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | """ 4 | test_pacman-mirrors 5 | ---------------------------------- 6 | 7 | Tests for `pacman-mirrors` module. 8 | """ 9 | 10 | import unittest 11 | from unittest.mock import patch 12 | 13 | from pacman_mirrors.functions import cliFn 14 | from pacman_mirrors.functions import configFn 15 | from pacman_mirrors.pacman_mirrors import PacmanMirrors 16 | from . import mock_configuration as conf 17 | 18 | test_conf = { 19 | "branch": "stable", 20 | "branches": conf.BRANCHES, 21 | "config_file": conf.CONFIG_FILE, 22 | "custom_file": conf.CUSTOM_FILE, 23 | "method": "rank", 24 | "work_dir": conf.WORK_DIR, 25 | "mirror_file": conf.MIRROR_FILE, 26 | "mirror_list": conf.MIRROR_LIST, 27 | "no_update": False, 28 | "country_pool": [], 29 | "protocols": [], 30 | "repo_arch": conf.REPO_ARCH, 31 | "status_file": conf.STATUS_FILE, 32 | "ssl_verify": True, 33 | "url_mirrors_json": conf.URL_MIRROR_JSON, 34 | "url_status_json": conf.URL_STATUS_JSON, 35 | "x32": False 36 | } 37 | 38 | 39 | class TestCommandLineParse(unittest.TestCase): 40 | """Pacman Mirrors Test suite""" 41 | def setUp(self): 42 | """Setup tests""" 43 | pass 44 | 45 | # @patch("os.getuid") 46 | # @patch.object(configFn, "setup_config") 47 | # def test_arg_branch_unstable(self, mock_build_config, mock_os_getuid): 48 | # """TEST: CLI config[branch] from ARG '-b unstable'""" 49 | # mock_os_getuid.return_value = 0 50 | # mock_build_config.return_value = test_conf 51 | # with unittest.mock.patch("sys.argv", 52 | # ["pacman-mirrors", 53 | # "-b", "unstable"]): 54 | # app = PacmanMirrors() 55 | # app.config["config_file"] = conf.CONFIG_FILE 56 | # app.config = configFn.setup_config() 57 | # cli.parse_command_line(app, True) 58 | # assert app.config["branch"] == "unstable" 59 | # 60 | # @patch("os.getuid") 61 | # @patch.object(configFn, "setup_config") 62 | # def test_arg_branch_testing(self, mock_build_config, mock_os_getuid): 63 | # """TEST: CLI config[branch] from ARG '-b testing'""" 64 | # mock_os_getuid.return_value = 0 65 | # mock_build_config.return_value = test_conf 66 | # with unittest.mock.patch("sys.argv", 67 | # ["pacman-mirrors", 68 | # "-b", "testing"]): 69 | # app = PacmanMirrors() 70 | # app.config["config_file"] = conf.CONFIG_FILE 71 | # app.config = configFn.setup_config() 72 | # cli.parse_command_line(app, True) 73 | # assert app.config["branch"] == "testing" 74 | 75 | @patch("os.getuid") 76 | @patch.object(configFn, "setup_config") 77 | def test_arg_method(self, mock_build_config, mock_os_getuid): 78 | """TEST: CLI config[method] from ARG '-m random'""" 79 | mock_os_getuid.return_value = 0 80 | mock_build_config.return_value = test_conf 81 | with unittest.mock.patch("sys.argv", 82 | ["pacman-mirrors", 83 | "-m", "random"]): 84 | app = PacmanMirrors() 85 | app.config["config_file"] = conf.CONFIG_FILE 86 | app.config = configFn.setup_config() 87 | cliFn.parse_command_line(app, True) 88 | assert app.config["method"] == "random" 89 | 90 | @patch("os.getuid") 91 | @patch.object(configFn, "setup_config") 92 | def test_arg_onlycountry(self, mock_build_config, mock_os_getuid): 93 | """TEST: CLI config[only_country] from ARG '-c France,Germany'""" 94 | mock_os_getuid.return_value = 0 95 | mock_build_config.return_value = test_conf 96 | with unittest.mock.patch("sys.argv", 97 | ["pacman-mirrors", 98 | "-c", "France,Germany"]): 99 | app = PacmanMirrors() 100 | app.config["config_file"] = conf.CONFIG_FILE 101 | app.config = configFn.setup_config() 102 | cliFn.parse_command_line(app, True) 103 | assert app.config["country_pool"] == ["France", "Germany"] 104 | 105 | @patch("os.getuid") 106 | @patch.object(configFn, "setup_config") 107 | def test_arg_geoip(self, mock_build_config, mock_os_getuid): 108 | """TEST: CLI geoip is True from ARG '--geoip'""" 109 | mock_os_getuid.return_value = 0 110 | mock_build_config.return_value = test_conf 111 | with unittest.mock.patch("sys.argv", 112 | ["pacman-mirrors", 113 | "--geoip"]): 114 | app = PacmanMirrors() 115 | app.config["config_file"] = conf.CONFIG_FILE 116 | app.config = configFn.setup_config() 117 | cliFn.parse_command_line(app, True) 118 | assert app.geoip is True 119 | 120 | @patch("os.getuid") 121 | @patch.object(configFn, "setup_config") 122 | def test_arg_fasttrack(self, mock_build_config, mock_os_getuid): 123 | """TEST: CLI fasttrack is 5 from ARG '-f 5'""" 124 | mock_os_getuid.return_value = 0 125 | mock_build_config.return_value = test_conf 126 | with unittest.mock.patch("sys.argv", 127 | ["pacman-mirrors", 128 | "-f5"]): 129 | app = PacmanMirrors() 130 | app.config["config_file"] = conf.CONFIG_FILE 131 | app.config = configFn.setup_config() 132 | cliFn.parse_command_line(app, True) 133 | assert app.fasttrack == 5 134 | 135 | @patch("os.getuid") 136 | @patch.object(configFn, "setup_config") 137 | def test_arg_interactive(self, mock_build_config, mock_os_getuid): 138 | """TEST: CLI interactive is true from ARG '-i'""" 139 | mock_os_getuid.return_value = 0 140 | mock_build_config.return_value = test_conf 141 | with unittest.mock.patch("sys.argv", 142 | ["pacman-mirrors", 143 | "-i"]): 144 | app = PacmanMirrors() 145 | app.config["config_file"] = conf.CONFIG_FILE 146 | app.config = configFn.setup_config() 147 | cliFn.parse_command_line(app, True) 148 | assert app.interactive is True 149 | 150 | @patch("os.getuid") 151 | @patch.object(configFn, "setup_config") 152 | def test_arg_max_wait_time(self, mock_build_config, mock_os_getuid): 153 | """TEST: CLI max_wait_time is 5 from ARG '-t 5'""" 154 | mock_os_getuid.return_value = 0 155 | mock_build_config.return_value = test_conf 156 | with unittest.mock.patch("sys.argv", 157 | ["pacman-mirrors", 158 | "-t5"]): 159 | app = PacmanMirrors() 160 | app.config["config_file"] = conf.CONFIG_FILE 161 | app.config = configFn.setup_config() 162 | cliFn.parse_command_line(app, True) 163 | assert app.max_wait_time == 5 164 | 165 | @patch("os.getuid") 166 | @patch.object(configFn, "setup_config") 167 | def test_arg_quiet(self, mock_build_config, mock_os_getuid): 168 | """TEST: CLI quiet is True from ARG '-q'""" 169 | mock_os_getuid.return_value = 0 170 | mock_build_config.return_value = test_conf 171 | with unittest.mock.patch("sys.argv", 172 | ["pacman-mirrors", 173 | "-q"]): 174 | app = PacmanMirrors() 175 | app.config["config_file"] = conf.CONFIG_FILE 176 | app.config = configFn.setup_config() 177 | cliFn.parse_command_line(app, True) 178 | assert app.quiet is True 179 | 180 | def tearDown(self): 181 | """Tear down""" 182 | pass 183 | 184 | 185 | if __name__ == "__main__": 186 | unittest.main() 187 | -------------------------------------------------------------------------------- /tests/test_default_config.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | """ 4 | test_pacman-mirrors 5 | ---------------------------------- 6 | 7 | Tests for `pacman-mirrors` module. 8 | """ 9 | 10 | import unittest 11 | from unittest.mock import patch 12 | 13 | from pacman_mirrors.functions import configFn 14 | from pacman_mirrors.pacman_mirrors import PacmanMirrors 15 | from . import mock_configuration as conf 16 | 17 | test_conf = { 18 | "to_be_removed": conf.TO_BE_REMOVED, 19 | "branch": "stable", 20 | "branches": conf.BRANCHES, 21 | "config_file": conf.CONFIG_FILE, 22 | "custom_file": conf.CUSTOM_FILE, 23 | "method": "rank", 24 | "work_dir": conf.WORK_DIR, 25 | "mirror_file": conf.MIRROR_FILE, 26 | "mirror_list": conf.MIRROR_LIST, 27 | "no_update": False, 28 | "country_pool": [], 29 | "protocols": [], 30 | "repo_arch": conf.REPO_ARCH, 31 | "status_file": conf.STATUS_FILE, 32 | "ssl_verify": True, 33 | "url_mirrors_json": conf.URL_MIRROR_JSON, 34 | "url_status_json": conf.URL_STATUS_JSON, 35 | "x32": False 36 | } 37 | 38 | 39 | class TestDefaultConfig(unittest.TestCase): 40 | """Pacman Mirrors Test suite""" 41 | def setUp(self): 42 | """Setup tests""" 43 | pass 44 | 45 | @patch("os.getuid") 46 | @patch.object(configFn, "setup_config") 47 | def test_default_branch(self, mock_build_config, mock_os_getuid): 48 | """TEST: config[branch] = stable""" 49 | mock_os_getuid.return_value = 0 50 | mock_build_config.return_value = test_conf 51 | with unittest.mock.patch("sys.argv", 52 | ["pacman-mirrors", 53 | "-f1"]): 54 | app = PacmanMirrors() 55 | app.config["config_file"] = conf.CONFIG_FILE 56 | app.config = configFn.setup_config() 57 | assert app.config["branch"] == "stable" 58 | 59 | @patch("os.getuid") 60 | @patch.object(configFn, "setup_config") 61 | def test_default_method(self, mock_build_config, mock_os_getuid): 62 | """TEST: config[method] = rank""" 63 | mock_os_getuid.return_value = 0 64 | mock_build_config.return_value = test_conf 65 | with unittest.mock.patch("sys.argv", 66 | ["pacman-mirrors", 67 | "-f1"]): 68 | app = PacmanMirrors() 69 | app.config["config_file"] = conf.CONFIG_FILE 70 | app.config = configFn.setup_config() 71 | assert app.config["method"] == "rank" 72 | 73 | @patch("os.getuid") 74 | @patch.object(configFn, "setup_config") 75 | def test_default_mirrordir(self, mock_build_config, mock_os_getuid): 76 | """TEST: config[mirror_dir] = tests/mock/var/""" 77 | mock_os_getuid.return_value = 0 78 | mock_build_config.return_value = test_conf 79 | with unittest.mock.patch("sys.argv", 80 | ["pacman-mirrors", 81 | "-f1"]): 82 | app = PacmanMirrors() 83 | app.config = configFn.setup_config() 84 | assert app.config["work_dir"] == "tests/mock/var/" 85 | 86 | @patch("os.getuid") 87 | @patch.object(configFn, "setup_config") 88 | def test_default_mirrorfile(self, mock_build_config, mock_os_getuid): 89 | """TEST: config[mirror_file] = tests/mock/usr/mirrors.json""" 90 | mock_os_getuid.return_value = 0 91 | mock_build_config.return_value = test_conf 92 | with unittest.mock.patch("sys.argv", 93 | ["pacman-mirrors", 94 | "-f1"]): 95 | app = PacmanMirrors() 96 | app.config = configFn.setup_config() 97 | assert app.config["mirror_file"] == "tests/mock/usr/mirrors.json" 98 | 99 | @patch("os.getuid") 100 | @patch.object(configFn, "setup_config") 101 | def test_default_mirrorlist(self, mock_build_config, mock_os_getuid): 102 | """TEST: config[mirror_list] = tests/mock/etc/mirrorlist""" 103 | mock_os_getuid.return_value = 0 104 | mock_build_config.return_value = test_conf 105 | with unittest.mock.patch("sys.argv", 106 | ["pacman-mirrors", 107 | "-f1"]): 108 | app = PacmanMirrors() 109 | app.config = configFn.setup_config() 110 | assert app.config["mirror_list"] == "tests/mock/etc/mirrorlist" 111 | 112 | @patch("os.getuid") 113 | @patch.object(configFn, "setup_config") 114 | def test_default_noupdate(self, mock_build_config, mock_os_getuid): 115 | """TEST: config[no_update] = False""" 116 | mock_os_getuid.return_value = 0 117 | mock_build_config.return_value = test_conf 118 | with unittest.mock.patch("sys.argv", 119 | ["pacman-mirrors", 120 | "-f1"]): 121 | app = PacmanMirrors() 122 | app.config = configFn.setup_config() 123 | assert app.config["no_update"] is False 124 | 125 | @patch("os.getuid") 126 | @patch.object(configFn, "setup_config") 127 | def test_default_onlycountry(self, mock_build_config, mock_os_getuid): 128 | """TEST: config[only_country] = []""" 129 | mock_os_getuid.return_value = 0 130 | mock_build_config.return_value = test_conf 131 | with unittest.mock.patch("sys.argv", 132 | ["pacman-mirrors", 133 | "-f1"]): 134 | app = PacmanMirrors() 135 | app.config["config_file"] = conf.CONFIG_FILE 136 | app.config = configFn.setup_config() 137 | assert app.config["country_pool"] == [] 138 | 139 | def tearDown(self): 140 | """Tear down""" 141 | pass 142 | 143 | 144 | if __name__ == "__main__": 145 | unittest.main() 146 | -------------------------------------------------------------------------------- /tests/test_httpfn.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | """ 4 | test_pacman-mirrors 5 | ---------------------------------- 6 | 7 | Tests for `pacman-mirrors` module. 8 | """ 9 | 10 | import unittest 11 | from unittest.mock import patch 12 | 13 | from pacman_mirrors.functions import httpFn, configFn, cliFn, defaultFn 14 | from pacman_mirrors.pacman_mirrors import PacmanMirrors 15 | from . import mock_configuration as mock 16 | 17 | test_conf = { 18 | "branch": "stable", 19 | "branches": mock.BRANCHES, 20 | "config_file": mock.CONFIG_FILE, 21 | "custom_file": mock.CUSTOM_FILE, 22 | "method": "rank", 23 | "mirror_file": mock.MIRROR_FILE, 24 | "mirror_list": mock.MIRROR_LIST, 25 | "no_update": False, 26 | "country_pool": [], 27 | "protocols": [], 28 | "repo_arch": mock.REPO_ARCH, 29 | "status_file": mock.STATUS_FILE, 30 | "ssl_verify": True, 31 | "url_mirrors_json": mock.URL_MIRROR_JSON, 32 | "url_status_json": mock.URL_STATUS_JSON, 33 | "work_dir": mock.WORK_DIR, 34 | "x32": False 35 | } 36 | 37 | 38 | class TestHttpFn(unittest.TestCase): 39 | """Pacman Mirrors Test suite""" 40 | def setUp(self): 41 | """Setup tests""" 42 | pass 43 | 44 | @patch("os.getuid") 45 | @patch.object(httpFn, "get_geoip_country") 46 | @patch.object(configFn, "setup_config") 47 | def test_geoip_available(self, 48 | mock_build_config, 49 | mock_get_geoip_country, 50 | mock_os_getuid): 51 | """TEST: geoip country IS avaiable""" 52 | mock_os_getuid.return_value = 0 53 | mock_build_config.return_value = test_conf 54 | mock_get_geoip_country.return_value = ["Denmark"] 55 | with unittest.mock.patch("sys.argv", 56 | ["pacman-mirrors", 57 | "--geoip"]): 58 | app = PacmanMirrors() 59 | app.config = configFn.setup_config() 60 | cliFn.parse_command_line(app, True) 61 | defaultFn.load_default_mirror_pool(app) 62 | app.selected_countries = httpFn.get_geoip_country() 63 | assert app.selected_countries == ["Denmark"] 64 | 65 | # @patch("os.getuid") 66 | # @patch.object(httpFn, "get_geoip_country") 67 | # @patch.object(configFn, "setup_config") 68 | # def test_geoip_not_available(self, 69 | # mock_build_config, 70 | # mock_get_geoip_country, 71 | # mock_os_getuid): 72 | # """TEST: geoip country IS NOT available""" 73 | # mock_os_getuid.return_value = 0 74 | # mock_get_geoip_country.return_value = "Antarctica" 75 | # mock_build_config.return_value = test_conf 76 | # with unittest.mock.patch("sys.argv", 77 | # ["pacman-mirrors", 78 | # "--geoip"]): 79 | # app = PacmanMirrors() 80 | # app.config = configFn.setup_config() 81 | # cli.parse_command_line(app, True) 82 | # defaultFn.load_default_mirror_pool(app) 83 | # assert app.selected_countries == app.mirrors.country_pool 84 | 85 | def tearDown(self): 86 | """Tear down""" 87 | pass 88 | 89 | 90 | if __name__ == "__main__": 91 | unittest.main() 92 | -------------------------------------------------------------------------------- /tests/test_inital_values.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | """ 4 | test_pacman-mirrors 5 | ---------------------------------- 6 | 7 | Tests for `pacman-mirrors` module. 8 | """ 9 | 10 | import unittest 11 | from unittest.mock import patch 12 | 13 | from pacman_mirrors.pacman_mirrors import PacmanMirrors 14 | 15 | 16 | class TestInitialValues(unittest.TestCase): 17 | """Pacman Mirrors Test suite""" 18 | def setUp(self): 19 | """Setup tests""" 20 | pass 21 | 22 | @patch("os.getuid") 23 | def test_initial_custom(self, mock_os_getuid): 24 | """TEST: self.custom is False""" 25 | mock_os_getuid.return_value = 0 26 | with unittest.mock.patch("sys.argv", 27 | ["pacman-mirrors", "f1"]): 28 | app = PacmanMirrors() 29 | assert app.custom is False 30 | 31 | @patch("os.getuid") 32 | def test_initial_fasttrack(self, mock_os_getuid): 33 | """TEST: self.fasttrack is False""" 34 | mock_os_getuid.return_value = 0 35 | with unittest.mock.patch("sys.argv", 36 | ["pacman-mirrors", "-f1"]): 37 | app = PacmanMirrors() 38 | assert app.fasttrack is None 39 | 40 | @patch("os.getuid") 41 | def test_initial_geoip(self, mock_os_getuid): 42 | """TEST: self.geoip is False""" 43 | mock_os_getuid.return_value = 0 44 | with unittest.mock.patch("sys.argv", 45 | ["pacman-mirrors", "-f1"]): 46 | app = PacmanMirrors() 47 | assert app.geoip is False 48 | 49 | @patch("os.getuid") 50 | def test_initial_interactive(self, mock_os_getuid): 51 | """TEST: self.interactive is False""" 52 | mock_os_getuid.return_value = 0 53 | with unittest.mock.patch("sys.argv", 54 | ["pacman-mirrors", "-f1"]): 55 | app = PacmanMirrors() 56 | assert app.interactive is False 57 | 58 | @patch("os.getuid") 59 | def test_initial_max_wait_time(self, mock_os_getuid): 60 | """TEST: self.max_wait_time = 2""" 61 | mock_os_getuid.return_value = 0 62 | with unittest.mock.patch("sys.argv", 63 | ["pacman-mirrors", "-f1"]): 64 | app = PacmanMirrors() 65 | assert app.max_wait_time == 2 66 | 67 | @patch("os.getuid") 68 | def test_initial_network(self, mock_os_getuid): 69 | """TEST: self.network is True""" 70 | mock_os_getuid.return_value = 0 71 | with unittest.mock.patch("sys.argv", 72 | ["pacman-mirrors", "-f1"]): 73 | app = PacmanMirrors() 74 | assert app.network is True 75 | 76 | @patch("os.getuid") 77 | def test_initial_nodisplay(self, mock_os_getuid): 78 | """TEST: self.no_display is False""" 79 | mock_os_getuid.return_value = 0 80 | with unittest.mock.patch("sys.argv", 81 | ["pacman-mirrors", "-f1"]): 82 | app = PacmanMirrors() 83 | assert app.no_display is False 84 | 85 | @patch("os.getuid") 86 | def test_initial_no_mirrorlist(self, mock_os_getuid): 87 | """TEST: self.no_mirrorlist = False""" 88 | mock_os_getuid.return_value = 0 89 | with unittest.mock.patch("sys.argv", 90 | ["pacman-mirrors", "-g"]): 91 | app = PacmanMirrors() 92 | assert app.no_mirrorlist is False 93 | 94 | @patch("os.getuid") 95 | def test_initial_quiet(self, mock_os_getuid): 96 | """TEST: self.quiet is False""" 97 | mock_os_getuid.return_value = 0 98 | with unittest.mock.patch("sys.argv", 99 | ["pacman-mirrors", "-f1"]): 100 | app = PacmanMirrors() 101 | assert app.quiet is False 102 | 103 | @patch("os.getuid") 104 | def test_initial_selected_countries(self, mock_os_getuid): 105 | """TEST: self.selected_countries = []""" 106 | mock_os_getuid.return_value = 0 107 | with unittest.mock.patch("sys.argv", 108 | ["pacman-mirrors", "-f1"]): 109 | app = PacmanMirrors() 110 | assert app.selected_countries == [] 111 | 112 | def tearDown(self): 113 | """Tear down""" 114 | pass 115 | 116 | 117 | if __name__ == "__main__": 118 | unittest.main() 119 | -------------------------------------------------------------------------------- /tests/test_pacman_mirrors.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | """ 4 | test_pacman-mirrors 5 | ---------------------------------- 6 | 7 | Tests for `pacman-mirrors` module. 8 | """ 9 | import unittest 10 | from unittest.mock import patch 11 | 12 | from pacman_mirrors.builder import common, fasttrack 13 | from pacman_mirrors.functions import fileFn, configFn, cliFn, defaultFn 14 | from pacman_mirrors.functions import httpFn 15 | from pacman_mirrors.pacman_mirrors import PacmanMirrors 16 | from . import mock_configuration as conf 17 | 18 | test_conf = { 19 | "branch": "stable", 20 | "branches": conf.BRANCHES, 21 | "config_file": conf.CONFIG_FILE, 22 | "custom_file": conf.CUSTOM_FILE, 23 | "method": "rank", 24 | "work_dir": conf.WORK_DIR, 25 | "mirror_file": conf.MIRROR_FILE, 26 | "mirror_list": conf.MIRROR_LIST, 27 | "no_update": False, 28 | "country_pool": [], 29 | "protocols": [], 30 | "repo_arch": conf.REPO_ARCH, 31 | "status_file": conf.STATUS_FILE, 32 | "ssl_verify": True, 33 | "url_mirrors_json": conf.URL_MIRROR_JSON, 34 | "url_status_json": conf.URL_STATUS_JSON, 35 | "x32": False 36 | } 37 | 38 | 39 | class TestPacmanMirrors(unittest.TestCase): 40 | """Pacman Mirrors Test suite""" 41 | def setUp(self): 42 | """Setup tests""" 43 | pass 44 | 45 | @patch("os.getuid") 46 | @patch.object(configFn, "setup_config") 47 | def test_full_run_fasttrack(self, 48 | mock_build_config, 49 | mock_os_getuid): 50 | """TEST: pacman-mirrors -f5""" 51 | mock_os_getuid.return_value = 0 52 | mock_build_config.return_value = test_conf 53 | with unittest.mock.patch("sys.argv", 54 | ["pacman-mirrors", 55 | "-f5"]): 56 | app = PacmanMirrors() 57 | app.config = configFn.setup_config() 58 | fileFn.create_dir(test_conf["work_dir"]) 59 | cliFn.parse_command_line(app, True) 60 | httpFn.update_mirror_pool(app.config) 61 | defaultFn.load_default_mirror_pool(app) 62 | fasttrack.build_mirror_list(app, app.fasttrack) 63 | 64 | @patch("os.getuid") 65 | @patch.object(configFn, "setup_config") 66 | def test_full_run_random(self, 67 | mock_build_config, 68 | mock_os_getuid): 69 | """TEST: pacman-mirrors -c all -m random""" 70 | mock_os_getuid.return_value = 0 71 | mock_build_config.return_value = test_conf 72 | with unittest.mock.patch("sys.argv", 73 | ["pacman-mirrors", 74 | "-c", "all", 75 | "-m", "random"]): 76 | app = PacmanMirrors() 77 | app.config = configFn.setup_config() 78 | fileFn.create_dir(test_conf["work_dir"]) 79 | cliFn.parse_command_line(app, True) 80 | httpFn.update_mirror_pool(app.config) 81 | defaultFn.load_default_mirror_pool(app) 82 | common.build_mirror_list(app) 83 | 84 | @patch("os.getuid") 85 | @patch.object(configFn, "setup_config") 86 | def test_full_run_rank(self, 87 | mock_build_config, 88 | mock_os_getuid): 89 | """TEST: pacman-mirrors -c all""" 90 | mock_os_getuid.return_value = 0 91 | mock_build_config.return_value = test_conf 92 | with unittest.mock.patch("sys.argv", 93 | ["pacman-mirrors", 94 | "-c", "all"]): 95 | app = PacmanMirrors() 96 | app.config = configFn.setup_config() 97 | fileFn.create_dir(test_conf["work_dir"]) 98 | cliFn.parse_command_line(app, True) 99 | httpFn.update_mirror_pool(app.config) 100 | defaultFn.load_default_mirror_pool(app) 101 | common.build_mirror_list(app) 102 | 103 | def tearDown(self): 104 | """Tear down""" 105 | pass 106 | 107 | 108 | if __name__ == "__main__": 109 | unittest.main() 110 | -------------------------------------------------------------------------------- /tests/test_txt_colors.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | """ 4 | test_pacman-mirrors 5 | ---------------------------------- 6 | 7 | Tests for `pacman-mirrors` module. 8 | """ 9 | 10 | import unittest 11 | 12 | from pacman_mirrors.constants import txt 13 | 14 | 15 | class TestTextColors(unittest.TestCase): 16 | """Pacman Mirrors Test suite""" 17 | def setUp(self): 18 | """Setup tests""" 19 | pass 20 | 21 | def test_txt_err_color(self): 22 | """TEST: txt ERR_CLR""" 23 | assert txt.ERR_CLR is not None 24 | 25 | def test_txt_inf_color(self): 26 | """TEST: txt INF_CLR""" 27 | assert txt.INF_CLR is not None 28 | 29 | def test_txt_wrn_color(self): 30 | """TEST: txt WRN_COLOR""" 31 | assert txt.WRN_CLR is not None 32 | 33 | def tearDown(self): 34 | """Tear down""" 35 | pass 36 | 37 | 38 | if __name__ == "__main__": 39 | unittest.main() 40 | -------------------------------------------------------------------------------- /tests/test_txt_error_types.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | """ 4 | test_pacman-mirrors 5 | ---------------------------------- 6 | 7 | Tests for `pacman-mirrors` module. 8 | """ 9 | 10 | import unittest 11 | 12 | from pacman_mirrors.constants import txt 13 | 14 | 15 | class TestTextErrorTypes(unittest.TestCase): 16 | """Pacman Mirrors Test suite""" 17 | def setUp(self): 18 | """Setup tests""" 19 | pass 20 | 21 | def test_txt_error_type_timeout(self): 22 | """TEST: txt ERROR TYPE TIMEOUT""" 23 | assert txt.TIMEOUT is not None 24 | 25 | def test_txt_error_type_http_exception(self): 26 | """TEST: txt ERROR TYPE HTTP EXCEPTION""" 27 | assert txt.HTTP_EXCEPTION is not None 28 | 29 | def tearDown(self): 30 | """Tear down""" 31 | pass 32 | 33 | 34 | if __name__ == "__main__": 35 | unittest.main() 36 | -------------------------------------------------------------------------------- /tests/test_txt_help_arg_messages.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | """ 4 | test_pacman-mirrors 5 | ---------------------------------- 6 | 7 | Tests for `pacman-mirrors` module. 8 | """ 9 | 10 | import unittest 11 | 12 | from pacman_mirrors.constants import txt 13 | 14 | 15 | class TestTextHelpArgMessages(unittest.TestCase): 16 | """Pacman Mirrors Test suite""" 17 | def setUp(self): 18 | """Setup tests""" 19 | pass 20 | 21 | def test_txt_help_arg_api_get_branch(self): 22 | """TEST: txt HELP ARG API GET BRANCH""" 23 | assert txt.HLP_ARG_API_GET_BRANCH is not None 24 | 25 | def test_txt_help_arg_api_prefix(self): 26 | """TEST: txt HELP ARG API PREFIX""" 27 | assert txt.HLP_ARG_API_PREFIX is not None 28 | 29 | def test_txt_help_arg_api_protocols(self): 30 | """TEST: txt HELP ARG API PROTOCOLS""" 31 | assert txt.HLP_ARG_API_PROTOCOLS is not None 32 | 33 | def test_txt_help_arg_api_re_branch(self): 34 | """TEST: txt HELP ARG API REBRANCH""" 35 | assert txt.HLP_ARG_API_RE_BRANCH is not None 36 | 37 | def test_txt_help_arg_api_set_branch(self): 38 | """TEST: txt HELP ARG API SET BRANCH""" 39 | assert txt.HLP_ARG_API_SET_BRANCH is not None 40 | 41 | def test_txt_help_arg_api_url(self): 42 | """TEST: txt HELP ARG API URL""" 43 | assert txt.HLP_ARG_API_URL is not None 44 | 45 | def test_txt_help_arg_branch(self): 46 | """TEST: txt HELP ARG BRANCH""" 47 | assert txt.HLP_ARG_BRANCH is not None 48 | 49 | def test_txt_help_arg_country(self): 50 | """TEST: txt HELP ARG COUNTRY""" 51 | assert txt.HLP_ARG_COUNTRY is not None 52 | 53 | def test_txt_help_arg_default(self): 54 | """TEST: txt HELP ARG DEFAULT""" 55 | assert txt.HLP_ARG_DEFAULT is not None 56 | 57 | def test_txt_help_arg_fasttrack(self): 58 | """TEST: txt HELP ARG FASTTRACK""" 59 | assert txt.HLP_ARG_FASTTRACK is not None 60 | 61 | def test_txt_help_arg_generate(self): 62 | """TEST: txt HELP ARG GENERATE""" 63 | assert txt.HLP_ARG_GENERATE is not None 64 | 65 | def test_txt_help_arg_geoip(self): 66 | """TEST: txt HELP ARG GEOIP""" 67 | assert txt.HLP_ARG_GEOIP is not None 68 | 69 | def test_txt_help_arg_list(self): 70 | """TEST: txt HELP ARG LIST""" 71 | assert txt.HLP_ARG_LIST is not None 72 | 73 | def test_txt_help_arg_method(self): 74 | """TEST: txt HELP ARG METHOD""" 75 | assert txt.HLP_ARG_METHOD is not None 76 | 77 | def test_txt_help_arg_mirrorlist(self): 78 | """TEST: txt HELP ARG MIRRORLIST""" 79 | assert txt.HLP_ARG_NO_MIRRORLIST is not None 80 | 81 | def test_txt_help_arg_quiet(self): 82 | """TEST: txt HELP ARG QUIET""" 83 | assert txt.HLP_ARG_QUIET is not None 84 | 85 | def test_txt_help_arg_sync(self): 86 | """TEST: txt HELP ARG SYNC""" 87 | assert txt.HLP_ARG_SYNC is not None 88 | 89 | def test_txt_help_arg_timeout(self): 90 | """TEST: txt HELP ARG TIMEOUT""" 91 | assert txt.HLP_ARG_TIMEOUT is not None 92 | 93 | def test_txt_help_arg_version(self): 94 | """TEST: txt HELP ARG VERSION""" 95 | assert txt.HLP_ARG_VERSION is not None 96 | 97 | def tearDown(self): 98 | """Tear down""" 99 | pass 100 | 101 | 102 | if __name__ == "__main__": 103 | unittest.main() 104 | -------------------------------------------------------------------------------- /tests/test_txt_interactive_messages.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | """ 4 | test_pacman-mirrors 5 | ---------------------------------- 6 | 7 | Tests for `pacman-mirrors` module. 8 | """ 9 | 10 | import unittest 11 | 12 | from pacman_mirrors.constants import txt 13 | 14 | 15 | class TestTextInteractiveMessages(unittest.TestCase): 16 | """Pacman Mirrors Test suite""" 17 | def setUp(self): 18 | """Setup tests""" 19 | pass 20 | 21 | # interactive messages 22 | def test_txt_interactive_title(self): 23 | """TEST: txt INTERACTIVE TITLE""" 24 | assert txt.I_TITLE is not None 25 | 26 | def test_txt_interactive_title_random(self): 27 | """TEST: txt INTERACTIVE TITLE RANDOM""" 28 | assert txt.I_TITLE_RANDOM is not None 29 | 30 | def test_txt_interactive_list_title(self): 31 | """TEST: txt INTERACTIVE LIST TITLE""" 32 | assert txt.I_LIST_TITLE is not None 33 | 34 | def test_txt_interactive_use(self): 35 | """TEST: txt INTERACTIVE USE""" 36 | assert txt.I_USE is not None 37 | 38 | def test_txt_interactive_country(self): 39 | """TEST: txt INTERACTIVE COUNTRY""" 40 | assert txt.I_COUNTRY is not None 41 | 42 | def test_txt_interactive_response(self): 43 | """TEST: txt INTERACTIVE RESPONSE""" 44 | assert txt.I_RESPONSE is not None 45 | 46 | def test_txt_interactive_last_sync(self): 47 | """TEST: txt INTERACTIVE LAST SYNC""" 48 | assert txt.I_LAST_SYNC is not None 49 | 50 | def test_txt_interactive_url(self): 51 | """TEST: txt INTERACTIVE URL""" 52 | assert txt.I_URL is not None 53 | 54 | def test_txt_interactive_cancel(self): 55 | """TEST: txt INTERACTIVE CANCEL""" 56 | assert txt.I_CANCEL is not None 57 | 58 | def test_txt_interactive_confirm(self): 59 | """TEST: txt INTERACTIVE CONFIRM""" 60 | assert txt.I_CONFIRM is not None 61 | 62 | def test_txt_interactive_confirm_selection(self): 63 | """TEST: txt INTERACTIVE CONFIRM SELECTION""" 64 | assert txt.I_CONFIRM_SELECTION is not None 65 | 66 | def test_txt_interactive_use_these_mirrors(self): 67 | """TEST: txt INTERACTIVE USE THESE MIRRORS""" 68 | assert txt.I_USE_THESE_MIRRORS is not None 69 | 70 | def tearDown(self): 71 | """Tear down""" 72 | pass 73 | 74 | 75 | if __name__ == "__main__": 76 | unittest.main() 77 | -------------------------------------------------------------------------------- /tests/test_txt_message_types.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | """ 4 | test_pacman-mirrors 5 | ---------------------------------- 6 | 7 | Tests for `pacman-mirrors` module. 8 | """ 9 | 10 | import unittest 11 | 12 | from pacman_mirrors.constants import txt 13 | 14 | 15 | class TestTextMessageTypes(unittest.TestCase): 16 | """Pacman Mirrors Test suite""" 17 | def setUp(self): 18 | """Setup tests""" 19 | pass 20 | 21 | def test_txt_msg_type_error(self): 22 | """TEST: txt MESSAGE TYPE ERROR""" 23 | assert txt.ERROR is not None 24 | 25 | def test_txt_msg_type_info(self): 26 | """TEST: txt MESSAGE TYPE INFO""" 27 | assert txt.INFO is not None 28 | 29 | def test_txt_msg_type_warn(self): 30 | """TEST: txt MESSAGE TYPE WARN""" 31 | assert txt.WARN is not None 32 | 33 | def tearDown(self): 34 | """Tear down""" 35 | pass 36 | 37 | 38 | if __name__ == "__main__": 39 | unittest.main() 40 | -------------------------------------------------------------------------------- /tests/test_txt_messages.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | """ 4 | test_pacman-mirrors 5 | ---------------------------------- 6 | 7 | Tests for `pacman-mirrors` module. 8 | """ 9 | 10 | import unittest 11 | 12 | from pacman_mirrors.constants import txt 13 | 14 | 15 | class TestTextMessages(unittest.TestCase): 16 | """Pacman Mirrors Test suite""" 17 | def setUp(self): 18 | """Setup tests""" 19 | pass 20 | 21 | def test_txt_msg_api_conf_rebranch(self): 22 | """TEST: txt API CONF REBRANCH""" 23 | assert txt.API_CONF_RE_BRANCH is not None 24 | 25 | def test_txt_msg_api_conf_protocols(self): 26 | """TEST: txt API CONF PROTOCOLS""" 27 | assert txt.API_CONF_PROTOCOLS is not None 28 | 29 | def test_txt_msg_api_mirrorlist_rebranch(self): 30 | """TEST: txt API MIRRORLIST REBRANCH""" 31 | assert txt.API_MIRRORLIST_RE_BRANCH is not None 32 | 33 | def test_txt_msg_available_countries(self): 34 | """TEST: txt AVAAILABLE COUNTRIES""" 35 | assert txt.AVAILABLE_COUNTRIES is not None 36 | 37 | def test_txt_msg_download_file(self): 38 | """TEST: txt DOWNLOAD FILE""" 39 | assert txt.CANNOT_DOWNLOAD_FILE is not None 40 | 41 | def test_txt_msg_cannot_read_file(self): 42 | """TEST: txt CANNOT READ FILE""" 43 | assert txt.CANNOT_READ_FILE is not None 44 | 45 | def test_txt_msg_cannot_write_file(self): 46 | """TEST: txt CANNOT WRITE FILE""" 47 | assert txt.CANNOT_WRITE_FILE is not None 48 | 49 | def test_txt_msg_convert_custom_mirror_file(self): 50 | """TEST: txt CONVERT CUSTOM MIRROR FILE""" 51 | assert txt.CONVERT_CUSTOM_MIRROR_FILE is not None 52 | 53 | def test_txt_msg_custom_mirror_file(self): 54 | """TEST: txt CUSTOM MIRROR FILE""" 55 | assert txt.CUSTOM_MIRROR_FILE is not None 56 | 57 | def test_txt_msg_custom_mirror_file_saved(self): 58 | """TEST: txt CUSTOM MIRROR FILE SAVED""" 59 | assert txt.CUSTOM_MIRROR_FILE_SAVED is not None 60 | 61 | def test_txt_msg_custom_mirror_list(self): 62 | """TEST: txt CUSTOM MIRROR LIST""" 63 | assert txt.CUSTOM_MIRROR_LIST is not None 64 | 65 | def test_txt_msg_deprecated_argument(self): 66 | """TEST: txt DEPRECATED ARGUMENT""" 67 | assert txt.DEPRECATED_ARGUMENT is not None 68 | 69 | def test_txt_msg_does_not_exist(self): 70 | """TEST: txt DOES NOT EXIST""" 71 | assert txt.DOES_NOT_EXIST is not None 72 | 73 | def test_txt_msg_downloading_mirror_file(self): 74 | """TEST: txt DOWNLOADING MIRROR FILE""" 75 | assert txt.DOWNLOADING_MIRROR_FILE is not None 76 | 77 | def test_txt_msg_falling_back(self): 78 | """TEST: txt FALLING BACK""" 79 | assert txt.FALLING_BACK is not None 80 | 81 | def test_txt_msg_internet_down(self): 82 | """TEST: txt INTERNET DOWN""" 83 | assert txt.INTERNET_DOWN is not None 84 | 85 | def test_txt_msg_internet_alternative(self): 86 | """TEST: txt INTERNET ALTERNATIVE""" 87 | assert txt.INTERNET_ALTERNATIVE is not None 88 | 89 | def test_txt_msg_is_missing(self): 90 | """TEST: txt IS MISSING""" 91 | assert txt.IS_MISSING is not None 92 | 93 | def test_txt_msg_mirror_file(self): 94 | """TEST: txt MIRROR FILE""" 95 | assert txt.MIRROR_FILE is not None 96 | 97 | def test_txt_msg_mirror_list_generated_on(self): 98 | """TEST: txt MIRROR_LIST_GENERATED_ON""" 99 | assert txt.MIRROR_LIST_GENERATED_ON is not None 100 | 101 | def test_txt_msg_mirror_list_custom_header(self): 102 | """TEST: txt MIRROR_LIST_CUSTOM_HEADER""" 103 | assert txt.MIRROR_LIST_CUSTOM_HEADER is not None 104 | 105 | def test_txt_msg_mirror_list_custom_reset(self): 106 | """TEST: txt MIRROR_LIST_CUSTOM_RESET""" 107 | assert txt.MIRROR_LIST_CUSTOM_RESET is not None 108 | 109 | def test_txt_msg_mirror_list_default_header(self): 110 | """TEST: txt MIRROR_LIST_DEFAULT_HEADER""" 111 | assert txt.MIRROR_LIST_DEFAULT_HEADER is not None 112 | 113 | def test_txt_msg_mirror_list_default_modify(self): 114 | """TEST: txt MIRROR_LIST_DEFAULT_MODIFY""" 115 | assert txt.MIRROR_LIST_DEFAULT_MODIFY is not None 116 | 117 | def test_txt_msg_mirror_list_saved(self): 118 | """TEST: txt MIRROR LIST SAVED""" 119 | assert txt.MIRROR_LIST_SAVED is not None 120 | 121 | def test_txt_msg_mirror_ranking_na(self): 122 | """TEST: txt MIRROR RANKING NA""" 123 | assert txt.MIRROR_RANKING_NA is not None 124 | 125 | def test_txt_msg_modify_default(self): 126 | """TEST: txt MODIFY_DEFAULT""" 127 | assert txt.MODIFY_DEFAULT is not None 128 | 129 | def test_txt_msg_must_be_root(self): 130 | """TEST: txt MUST BE ROOT""" 131 | assert txt.MUST_BE_ROOT is not None 132 | 133 | def test_txt_msg_no_change(self): 134 | """TEST: txt NO CHANGE""" 135 | assert txt.NO_CHANGE is not None 136 | 137 | def test_txt_msg_no_selection(self): 138 | """TEST: txt NO SELECTION""" 139 | assert txt.NO_SELECTION is not None 140 | 141 | def test_txt_msg_option(self): 142 | """TEST: txt OPTION""" 143 | assert txt.OPTION is not None 144 | 145 | def test_txt_msg_please_use(self): 146 | """TEST: txt PLEASE USE""" 147 | assert txt.PLEASE_USE is not None 148 | 149 | def test_txt_msg_query_mirrors(self): 150 | """TEST: txt QUERY MIRRORS""" 151 | assert txt.QUERY_MIRRORS is not None 152 | 153 | def test_txt_msg_randomizing_servers(self): 154 | """TEST: txt RANDOMIZING SERVERS""" 155 | assert txt.RANDOMIZING_SERVERS is not None 156 | 157 | def test_txt_msg_remove_custom_config(self): 158 | """TEST: txt REMOVE CUSTOM CONFIG""" 159 | assert txt.REMOVE_CUSTOM_CONFIG is not None 160 | 161 | def test_txt_msg_modify_custom(self): 162 | """TEST: txt MODIFY_CUSTOM""" 163 | assert txt.MODIFY_CUSTOM is not None 164 | 165 | def test_txt_msg_takes_time(self): 166 | """TEST: txt TAKES TIME""" 167 | assert txt.TAKES_TIME is not None 168 | 169 | def test_txt_msg_unknown_country(self): 170 | """TEST: txt UNKNOWN COUNTRY""" 171 | assert txt.UNKNOWN_COUNTRY is not None 172 | 173 | def test_txt_msg_use_zero_for_all(self): 174 | """TEST: txt USE_ZERO_FOR_ALL""" 175 | assert txt.USE_ZERO_FOR_ALL is not None 176 | 177 | def test_txt_msg_using_all_mirrors(self): 178 | """TEST: txt USING ALL MIRRORS""" 179 | assert txt.USING_ALL_MIRRORS is not None 180 | 181 | def test_txt_msg_using_custom_file(self): 182 | """TEST: txt USING CUSTOM FILE""" 183 | assert txt.USING_CUSTOM_FILE is not None 184 | 185 | def test_txt_msg_using_default_file(self): 186 | """TEST: txt USING DEFAULT FILE""" 187 | assert txt.USING_DEFAULT_FILE is not None 188 | 189 | def test_txt_msg_writing_mirror_list(self): 190 | """TEST: txt WRITING MIRROR LIST""" 191 | assert txt.WRITING_MIRROR_LIST is not None 192 | 193 | def test_txt_api_arguments_error(self): 194 | """TEST: txt API_ARGUMENTS_ERROR""" 195 | assert txt.API_ARGUMENTS_ERROR is not None 196 | 197 | def test_txt_interactive_arguments_error(self): 198 | """TEST: txt API_INTERACTIVE_ERROR""" 199 | assert txt.INTERACTIVE_ARGUMENTS_ERROR is not None 200 | 201 | def tearDown(self): 202 | """Tear down""" 203 | pass 204 | 205 | 206 | if __name__ == "__main__": 207 | unittest.main() 208 | -------------------------------------------------------------------------------- /tests/test_txt_mirror_status.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | """ 4 | test_pacman-mirrors 5 | ---------------------------------- 6 | 7 | Tests for `pacman-mirrors` module. 8 | """ 9 | 10 | import unittest 11 | 12 | from pacman_mirrors.constants import txt 13 | 14 | 15 | class TestTextMirrorStatus(unittest.TestCase): 16 | """Pacman Mirrors Test suite""" 17 | def setUp(self): 18 | """Setup tests""" 19 | pass 20 | 21 | # mirror status constants 22 | def test_txt_lastsync_ok(self): 23 | """TEST: txt LASTSYNC_OK""" 24 | assert txt.LASTSYNC_OK is not None 25 | 26 | def test_txt_lastsync_na(self): 27 | """TEST: txt LASTSYNC_NA""" 28 | assert txt.LASTSYNC_NA is not None 29 | 30 | def test_txt_server_bad(self): 31 | """TEST: txt SERVER_BAD""" 32 | assert txt.SERVER_BAD is not None 33 | 34 | def test_txt_server_res(self): 35 | """TEST: txt SERVER_RES""" 36 | assert txt.SERVER_RES is not None 37 | 38 | def tearDown(self): 39 | """Tear down""" 40 | pass 41 | 42 | 43 | if __name__ == "__main__": 44 | unittest.main() 45 | -------------------------------------------------------------------------------- /tests/test_txt_non_translatable.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | """ 4 | test_pacman-mirrors 5 | ---------------------------------- 6 | 7 | Tests for `pacman-mirrors` module. 8 | """ 9 | 10 | import unittest 11 | 12 | from pacman_mirrors.constants import txt 13 | 14 | 15 | class TestTextConstants(unittest.TestCase): 16 | """Pacman Mirrors Test suite""" 17 | def setUp(self): 18 | """Setup tests""" 19 | pass 20 | 21 | def test_txt_houston(self): 22 | """TEST: txt HOUSTON""" 23 | assert txt.HOUSTON is not None 24 | 25 | def test_txt_override_opt(self): 26 | """TEST: txt OVERRIDE_OPT""" 27 | assert txt.OVERRIDE_OPT is not None 28 | 29 | def test_txt_repo_server(self): 30 | """TEST: txt REPO_SERVER""" 31 | assert txt.REPO_SERVER is not None 32 | 33 | def test_txt_reset_custom_file(self): 34 | """TEST: txt RESET_CUSTOM_FILE""" 35 | assert txt.MODIFY_CUSTOM is not None 36 | 37 | def test_txt_prefix_tip(self): 38 | """TEST: txt PREFIX_TIP""" 39 | assert txt.PREFIX_TIP is not None 40 | 41 | def tearDown(self): 42 | """Tear down""" 43 | pass 44 | 45 | 46 | if __name__ == "__main__": 47 | unittest.main() 48 | -------------------------------------------------------------------------------- /tests/test_txt_options.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | """ 4 | test_pacman-mirrors 5 | ---------------------------------- 6 | 7 | Tests for `pacman-mirrors` module. 8 | """ 9 | 10 | import unittest 11 | 12 | from pacman_mirrors.constants import txt 13 | 14 | 15 | class TestTextOptions(unittest.TestCase): 16 | """Pacman Mirrors Test suite""" 17 | def setUp(self): 18 | """Setup tests""" 19 | pass 20 | 21 | # options 22 | def test_txt_opt_random(self): 23 | """TEST: txt OPT_RANDOM""" 24 | assert txt.OPT_RANDOM is not None 25 | 26 | def test_txt_opt_country(self): 27 | """TEST: txt OPT_COUNTRY""" 28 | assert txt.OPT_COUNTRY is not None 29 | 30 | def tearDown(self): 31 | """Tear down""" 32 | pass 33 | 34 | 35 | if __name__ == "__main__": 36 | unittest.main() 37 | -------------------------------------------------------------------------------- /tests/test_txt_special_words.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | """ 4 | test_pacman-mirrors 5 | ---------------------------------- 6 | 7 | Tests for `pacman-mirrors` module. 8 | """ 9 | 10 | import unittest 11 | 12 | from pacman_mirrors.constants import txt 13 | 14 | 15 | class TestTextSpecialWords(unittest.TestCase): 16 | """Pacman Mirrors Test suite""" 17 | def setUp(self): 18 | """Setup tests""" 19 | pass 20 | 21 | # special words 22 | def test_txt_special_word_path(self): 23 | """TEST: txt SPECIAL WORD PATH""" 24 | assert txt.PATH is not None 25 | 26 | def test_txt_special_word_file(self): 27 | """TEST: txt SPECIAL WORD FILE""" 28 | assert txt.FILE is not None 29 | 30 | def test_txt_special_word_seconds(self): 31 | """TEST: txt SPECIAL WORD SECONDS""" 32 | assert txt.SECONDS is not None 33 | 34 | def test_txt_special_word_number(self): 35 | """TEST: txt SPECIAL WORD NUMBER""" 36 | assert txt.NUMBER is not None 37 | 38 | def test_txt_special_word_usage(self): 39 | """TEST: txt SPECIAL WORD USAGE""" 40 | assert txt.USAGE is not None 41 | 42 | def test_txt_special_word_country(self): 43 | """TEST: txt SPECIAL WORD COUNTRY""" 44 | assert txt.COUNTRY is not None 45 | 46 | def test_txt_special_word_prefix(self): 47 | """TEST: txt SPECIAL WORD PREFIX""" 48 | assert txt.PREFIX is not None 49 | 50 | def test_txt_special_word_method(self): 51 | """TEST: txt SPECIAL WORD METHOD""" 52 | assert txt.METHOD is not None 53 | 54 | def test_txt_special_word_methods(self): 55 | """TEST: txt SPECIAL WORD METHODS""" 56 | assert txt.METHODS is not None 57 | 58 | def test_txt_special_word_branch(self): 59 | """TEST: txt SPECIAL WORD BRANCH""" 60 | assert txt.BRANCH is not None 61 | 62 | def test_txt_special_word_proto(self): 63 | """TEST: txt SPECIAL WORD PROTO""" 64 | assert txt.PROTO is not None 65 | 66 | def test_txt_special_word_misc(self): 67 | """TEST: txt SPECIAL WORD MISC""" 68 | assert txt.MISC is not None 69 | 70 | def test_txt_special_word_api(self): 71 | """TEST: txt SPECIAL WORD API""" 72 | assert txt.API is not None 73 | 74 | def test_txt_special_word_url(self): 75 | """TEST: txt SPECIAL WORD URL""" 76 | assert txt.URL is not None 77 | 78 | def tearDown(self): 79 | """Tear down""" 80 | pass 81 | 82 | 83 | if __name__ == "__main__": 84 | unittest.main() 85 | -------------------------------------------------------------------------------- /tox.ini: -------------------------------------------------------------------------------- 1 | [tox] 2 | envlist = py34 3 | 4 | [testenv] 5 | setenv = 6 | PYTHONPATH = {toxinidir}:{toxinidir}/pacman-mirrors 7 | commands = python setup.py test 8 | deps = 9 | -r{toxinidir}/requirements.txt 10 | --------------------------------------------------------------------------------