From 15aae28e54c3fdfe2eb4fd4563cf095147e16fa2 Mon Sep 17 00:00:00 2001 From: Erich Eckner Date: Sat, 5 Sep 2020 20:42:56 +0200 Subject: reflector-2020.8.tar.xz --- CHANGELOG | 5 +++++ Reflector.py | 40 ++++++++++++++++++++++++++++++++-------- man.md/reflector.1.md | 4 ++-- man/reflector.1.gz | Bin 667 -> 667 bytes reflector.conf | 27 +++++++++++++++++++++++++++ reflector.service | 9 +++++++++ reflector.timer | 11 +++++++++++ setup.py | 2 +- 8 files changed, 87 insertions(+), 11 deletions(-) create mode 100644 reflector.conf create mode 100644 reflector.service create mode 100644 reflector.timer diff --git a/CHANGELOG b/CHANGELOG index 1fa5c7e..09ee7a9 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,8 @@ +# 2020-08-20 +* Added support for comma-separated values in list arguments (country, protocol). +* Added support for argument files with the "@" prefix. +* Added systemd integration (inspired by David Runge's request (Arch Linux FS#63910) and Silvio Knizek's "reflector-timer" AUR package. + # 2019-03-02 * Refactored code to make it more modular. The MirrorStatus class remains with all of its functions for backwards compatibility but this will either be removed for further refactored in the future. * Added `--isos`, `--ipv4` and `--ipv6` options. diff --git a/Reflector.py b/Reflector.py index 5263316..1665090 100644 --- a/Reflector.py +++ b/Reflector.py @@ -35,6 +35,7 @@ import os import pipes import queue import re +import shlex import socket import subprocess import sys @@ -61,7 +62,7 @@ MIRRORLIST_ENTRY_FORMAT = "Server = " + MIRROR_URL_FORMAT + "\n" DEFAULT_CONNECTION_TIMEOUT = 5 DEFAULT_CACHE_TIMEOUT = 300 -DEFAULT_N_THREADS = 5 +DEFAULT_N_THREADS = os.cpu_count() SORT_TYPES = { 'age': 'last server synchronization', @@ -638,8 +639,6 @@ def add_arguments(parser): ''' Add reflector arguments to the argument parser. ''' - parser = argparse.ArgumentParser(description='retrieve and filter a list of the latest Arch Linux mirrors') - parser.add_argument( '--connection-timeout', type=int, metavar='n', default=DEFAULT_CONNECTION_TIMEOUT, help='The number of seconds to wait before a connection times out. Default: %(default)s' @@ -678,7 +677,7 @@ def add_arguments(parser): parser.add_argument( '--threads', type=int, metavar='n', default=DEFAULT_N_THREADS, - help='The maximum number of threads to use when rating mirrors. Default: %(default)s' + help='The maximum number of threads to use when rating mirrors. Keep in mind that this may skew your results if your connection is saturated. Default: %(default)s (number of detected CPUs)' ) parser.add_argument( @@ -703,7 +702,7 @@ def add_arguments(parser): filters.add_argument( '-c', '--country', dest='countries', action='append', metavar='', - help='Match one of the given countries (case-sensitive). Use "--list-countries" to see which are available.' + help='Match one of the given countries (case-sensitive). Multiple countries may be selected using commas (e.g. "France,Germany") or by passing this option multiple times. Use "--list-countries" to see which are available.' ) filters.add_argument( @@ -738,7 +737,7 @@ def add_arguments(parser): filters.add_argument( '-p', '--protocol', dest='protocols', action='append', metavar='', - help='Match one of the given protocols, e.g. "http", "ftp".' + help='Match one of the given protocols, e.g. "https" or "ftp". Multiple protocols may be selected using commas (e.g. "https,http") or by passing this option multiple times.' ) filters.add_argument( @@ -764,15 +763,40 @@ def add_arguments(parser): return parser +def split_list_args(args): + ''' + Split comma-separated list arguments into separate list elements. + ''' + if not args: + return + for arg in args: + yield from arg.split(',') + + +class MyArgumentParser(argparse.ArgumentParser): + ''' + Custom argument parser to support a more readable format in argument files. + ''' + def convert_arg_line_to_args(self, arg_line): + # Support comments and blank lines. + # content = arg_line.strip() + # if not content or content.startswith('#'): + # return list() + return shlex.split(arg_line, comments=True) + + def parse_args(args=None): ''' Parse command-line arguments. ''' - parser = argparse.ArgumentParser( - description='retrieve and filter a list of the latest Arch Linux mirrors' + parser = MyArgumentParser( + description='retrieve and filter a list of the latest Arch Linux mirrors', + fromfile_prefix_chars='@' ) parser = add_arguments(parser) options = parser.parse_args(args) + for list_arg in ('countries', 'protocols'): + setattr(options, list_arg, list(split_list_args(getattr(options, list_arg)))) return options diff --git a/man.md/reflector.1.md b/man.md/reflector.1.md index ef107ce..d91434b 100644 --- a/man.md/reflector.1.md +++ b/man.md/reflector.1.md @@ -33,13 +33,13 @@ reflector --latest 5 --sort rate --save /etc/pacman.d/mirrorlist Select the 200 most recently synchronized HTTP or HTTPS mirrors, sort them by download speed, and overwrite the file /etc/pacman.d/mirrorlist: ~~~{.sh} -reflector --latest 200 --protocol http --protocol https --sort rate --save /etc/pacman.d/mirrorlist +reflector --latest 200 --protocol http,https --sort rate --save /etc/pacman.d/mirrorlist ~~~ Select the HTTPS mirrors synchronized within the last 12 hours and located in either France or Germany, sort them by download speed, and overwrite the file `/etc/pacman.d/mirrorlist` with the results: ~~~{.sh} -reflector --country France --country Germany --age 12 --protocol https --sort rate --save /etc/pacman.d/mirrorlist +reflector --country France,Germany --age 12 --protocol https --sort rate --save /etc/pacman.d/mirrorlist ~~~ # See Also diff --git a/man/reflector.1.gz b/man/reflector.1.gz index 26d1712..d44062d 100644 Binary files a/man/reflector.1.gz and b/man/reflector.1.gz differ diff --git a/reflector.conf b/reflector.conf new file mode 100644 index 0000000..92eb3bf --- /dev/null +++ b/reflector.conf @@ -0,0 +1,27 @@ +# Reflector configuration file for the systemd service. +# +# Empty lines and lines beginning with "#" are ignored. All other lines should +# contain valid reflector command-line arguments. The lines are parsed with +# Python's shlex modules so standard shell syntax should work. All arguments are +# collected into a single argument list. +# +# See "reflector --help" for details. + +# Recommended Options + +# Set the output path where the mirrorlist will be saved (--save). +--save /etc/pacman.d/mirrorlist + +# Select the transfer protocol (--protocol). +--protocol https + +# Select the country (--country). +# Consult the list of available countries with "reflector --list-countries" and +# select the countries nearest to you or the ones that you trust. For example: +# --country France,Germany + +# Use only the most recently synchronized mirrors (--latest). +--latest 5 + +# Sort the mirrors by synchronization time (--sort). +--sort age diff --git a/reflector.service b/reflector.service new file mode 100644 index 0000000..67b0dce --- /dev/null +++ b/reflector.service @@ -0,0 +1,9 @@ +[Unit] +Description=Refresh Pacman mirrorlist with Reflector. +Documentation=https://wiki.archlinux.org/index.php/Reflector +Requires=network-online.target +After=network-online.target + +[Service] +Type=oneshot +ExecStart=/usr/bin/reflector @/etc/xdg/reflector/reflector.conf diff --git a/reflector.timer b/reflector.timer new file mode 100644 index 0000000..e4df93e --- /dev/null +++ b/reflector.timer @@ -0,0 +1,11 @@ +[Unit] +Description=Refresh Pacman mirrorlist weekly with Reflector. + +[Timer] +OnCalendar=weekly +Persistent=true +AccuracySec=1us +RandomizedDelaySec=12h + +[Install] +WantedBy=timers.target diff --git a/setup.py b/setup.py index 6fd2caa..f54b6ed 100644 --- a/setup.py +++ b/setup.py @@ -5,7 +5,7 @@ import time setup( name='''Reflector''', - version=time.strftime('%Y.%m.%d.%H.%M.%S', time.gmtime(1584790836)), + version=time.strftime('%Y.%m.%d.%H.%M.%S', time.gmtime(1597879351)), description='''A Python 3 module and script to retrieve and filter the latest Pacman mirror list.''', author='''Xyne''', author_email='''ac xunilhcra enyx, backwards''', -- cgit v1.2.3