From 426133acb4c0384fc4ff0050f5cd4bf4e8704085 Mon Sep 17 00:00:00 2001 From: Marius Konitzer Date: Wed, 8 Sep 2021 17:23:51 +0200 Subject: [PATCH 1/2] Migrate to Python 3 (and drop Python 2 support) --- README | 5 +---- brutha/__main__.py | 6 ++---- brutha/directory.py | 2 -- brutha/file.py | 2 -- brutha/output.py | 8 +++----- brutha/tree.py | 2 -- brutha/util.py | 2 -- setup.py | 9 +++------ 8 files changed, 9 insertions(+), 27 deletions(-) diff --git a/README b/README index 463826e..8438004 100644 --- a/README +++ b/README @@ -53,8 +53,7 @@ without issues except lower performance. Software requirements ~~~~~~~~~~~~~~~~~~~~~ -* Python 2 (2.6 or later) -* python-argparse (or Python 2.7 or later) +* Python 3 (3.2 or later) * `python-mutagen `_ * `sox `_ * for parallel runs, either `GNU make `_ @@ -139,13 +138,11 @@ Future ------ `brutha` is considered feature-complete. -Python 3 support is waiting for mutagen. If you want to help, here are some possibilities: * Support other formats (currently only FLAC to Ogg Vorbis, with Ogg Vorbis and MP3 as exact copies). * Make mutagen optional (only required for frequency / bit depth checks). -* Port mutagen to Python 3 * Support downmixing (5.1 to 2.0 for instance) Contributions can be sent in the form of git patches, to laurent@bachelier.name. diff --git a/brutha/__main__.py b/brutha/__main__.py index 428be7b..74d047d 100644 --- a/brutha/__main__.py +++ b/brutha/__main__.py @@ -1,11 +1,9 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -from __future__ import absolute_import, print_function - import argparse import sys from multiprocessing import cpu_count -from StringIO import StringIO +from io import StringIO from .output import OUTPUTS from .tree import Tree @@ -26,7 +24,7 @@ def main(): help="Compute ReplayGain if missing") parser.add_argument('-d', '--delete', action='store_true', help="Delete extraneous files in destination") - parser.add_argument('-o', '--output', default=output, choices=OUTPUTS.keys(), + parser.add_argument('-o', '--output', default=output, choices=list(OUTPUTS.keys()), help="Command list type") parser.add_argument('-R', '--maxrate', type=int, help="Maximum sample rate allowed (e.g. 44100)", metavar="RATE") diff --git a/brutha/directory.py b/brutha/directory.py index ab3170c..92ae995 100644 --- a/brutha/directory.py +++ b/brutha/directory.py @@ -1,6 +1,4 @@ # -*- coding: utf-8 -*- -from __future__ import absolute_import - import os import re diff --git a/brutha/file.py b/brutha/file.py index 1ccac12..e70f2d0 100644 --- a/brutha/file.py +++ b/brutha/file.py @@ -1,6 +1,4 @@ # -*- coding: utf-8 -*- -from __future__ import absolute_import - import os import re from datetime import datetime diff --git a/brutha/output.py b/brutha/output.py index 5de12db..566d78d 100644 --- a/brutha/output.py +++ b/brutha/output.py @@ -1,6 +1,4 @@ # -*- coding: utf-8 -*- -from __future__ import absolute_import, division, print_function - import subprocess from .util import require_executable @@ -48,7 +46,7 @@ def run(self, stream): assert line.startswith('#!') shebang = line[2:].split() p = subprocess.Popen(shebang, shell=False, stdin=subprocess.PIPE) - p.communicate(stream.getvalue()) + p.communicate(stream.getvalue().encode()) return p.returncode @@ -88,7 +86,7 @@ def _escape(self, line): def write(self, commands, stream): prefix = '' if self.echo else '@' - targets = ' '.join('d%s' % i for i in xrange(0, len(commands))) + targets = ' '.join('d%s' % i for i in range(0, len(commands))) print('.PHONY: all %s' % targets, file=stream) print('all: %s' % targets, file=stream) print(file=stream) @@ -105,7 +103,7 @@ def run(self, stream): addon = [] p = subprocess.Popen([require_executable('make', ['gmake', 'make']), '-f', '-'] + addon, shell=False, stdin=subprocess.PIPE) - p.communicate(stream.getvalue()) + p.communicate(stream.getvalue().encode()) return p.returncode diff --git a/brutha/tree.py b/brutha/tree.py index 2b7c2b0..6e4f565 100644 --- a/brutha/tree.py +++ b/brutha/tree.py @@ -1,6 +1,4 @@ # -*- coding: utf-8 -*- -from __future__ import absolute_import, print_function - import os from .directory import Directory, NotInteresting diff --git a/brutha/util.py b/brutha/util.py index d6a5c9e..532391e 100644 --- a/brutha/util.py +++ b/brutha/util.py @@ -1,6 +1,4 @@ # -*- coding: utf-8 -*- -from __future__ import absolute_import - import os diff --git a/setup.py b/setup.py index 84b2460..bc27602 100755 --- a/setup.py +++ b/setup.py @@ -5,10 +5,8 @@ from setuptools import setup -assert version_info >= (2, 6) +assert version_info >= (3, 2) # 'argparse' module requires Python 3.2 or later requirements = ['mutagen'] -if version_info < (2, 7): - requirements.append('argparse') setup( name='brutha', @@ -21,9 +19,8 @@ packages=['brutha'], install_requires=requirements, classifiers=[ - 'Programming Language :: Python :: 2', - 'Programming Language :: Python :: 2.6', - 'Programming Language :: Python :: 2.7', + 'Programming Language :: Python', + 'Programming Language :: Python :: 3', 'Operating System :: POSIX', 'Environment :: Console', 'License :: OSI Approved :: GNU General Public License v2 or later (GPLv2+)', From 2dd0a2035f1c47472e3cb7012f78b4300a563530 Mon Sep 17 00:00:00 2001 From: Marius Konitzer Date: Wed, 8 Sep 2021 17:47:52 +0200 Subject: [PATCH 2/2] Convert README from reStructuredText to GitHub-friendly Markdown --- MANIFEST.in | 2 +- README => README.md | 118 +++++++++++++++++++------------------------- setup.py | 3 +- 3 files changed, 54 insertions(+), 69 deletions(-) rename README => README.md (56%) diff --git a/MANIFEST.in b/MANIFEST.in index c41487f..64ad321 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1 +1 @@ -include README LICENSE +include README.md LICENSE diff --git a/README b/README.md similarity index 56% rename from README rename to README.md index 8438004..cd257f2 100644 --- a/README +++ b/README.md @@ -1,9 +1,6 @@ -====== -brutha -====== +# brutha -Description ------------ +## Description *brutha* is an answer to the utter failure of sound conversion tools. @@ -13,15 +10,15 @@ to a provided directory, with a "synchronization" behavior. By carefully keeping the files' timestamps, it also allows that destination to be easily rsynced elsewhere, and thus avoid any useless transfers. -Due to the usage of formats with Ogg containers, no tags are lost in the process of converting FLAC to Ogg Vorbis. +Due to the usage of formats with Ogg containers, no tags are lost in the +process of converting FLAC to Ogg Vorbis. Since transcoding requires a lot of CPU time, it is useful to run -as many jobs as possible in parallel. `brutha` will try to make use of -powerful, time-tested tools (either `GNU make`, `GNU parallel`, +as many jobs as possible in parallel. *brutha* will try to make use of +powerful, time-tested tools (either *GNU make*, *GNU parallel*, or similar implementations) to do so. It's not perfect but good enough while keeping it simple. - To our knowledge, no other solution can fully: * avoid encoding again files that were already processed at an earlier run @@ -34,61 +31,55 @@ To our knowledge, no other solution can fully: * save space for lossy files by using hardlinks or reflinks * not be an annoying GUI -To sum up, `brutha` is a music converter tailored to audiophiles, +To sum up, *brutha* is a music converter tailored to audiophiles, who want to convert their huge collections to more portable destinations, with the highest quality/size ratio in mind. -`brutha` is very simple and rests on the shoulders on giants: +*brutha* is very simple and rests on the shoulders of giants: FLAC, Ogg Vorbis, sox, Python, mutagen, GNU Make, GNU Parallel, Bash, etc. +## Requirements -Requirements ------------- - -The first one is space. Since you can store locally all the source files, we suppose you -also can store the smaller destination files locally. Alternatively, -you will be able to sync to a portable player, a remote filesystem (NFS, sshfs, etc.) -without issues except lower performance. +The first one is space. Since you can store locally all the source +files, we suppose you also can store the smaller destination files +locally. Alternatively, you will be able to sync to a portable player, a +remote filesystem (NFS, sshfs, etc.) without issues except lower +performance. -Software requirements -~~~~~~~~~~~~~~~~~~~~~ +### Software requirements * Python 3 (3.2 or later) -* `python-mutagen `_ -* `sox `_ -* for parallel runs, either `GNU make `_ - or `GNU parallel `_, or a similar implementation - -Optional : - -* `vorbisgain `_ for ``--gain`` - +* [python-mutagen](http://pypi.python.org/pypi/mutagen) +* [sox](http://sox.sourceforge.net/) +* for parallel runs, either + [GNU make](http://www.gnu.org/software/make/make.html) or + [GNU parallel](http://www.gnu.org/software/parallel/) or + a similar implementation -Usage ------ +Optional: +* [vorbisgain](https://sjeng.org/vorbisgain.html) for `--gain` -:: +## Usage brutha [options] SOURCE DESTINATION -``brutha -h`` provides help for all available options. +`brutha -h` provides help for all available options. -You can run ``python -m brutha`` to use it without installing. +You can run `python -m brutha` to use it without installing. -Default values -~~~~~~~~~~~~~~ -`brutha` tries to detect how many cores you have -(run ``brutha -h`` to check the default for ``-j``). +### Default values + +*brutha* tries to detect how many cores you have +(run `brutha -h` to check the default for `-j`). It also tries to use a parallel method -(``make`` or ``parallel`` instead of ``sh``) if available. +(`make` or `parallel` instead of `sh`) if available. By default, it does not run or delete anything; when you are experienced -with its usage, you will likely call it with ``-x`` (execute) and ``-d`` (delete). +with its usage, you will likely call it with `-x` (execute) and `-d` (delete). -Examples -~~~~~~~~ +### Examples -A typical use would be:: +A typical use would be: brutha -d -x -q6 -R44100 -B16 ~/Music /mnt/portable_music_player/Music @@ -96,53 +87,46 @@ This downsamples music to 16/44 as most portable players don't handle 24/96 well (-R44100 -B16), encodes FLAC to Ogg at a reasonable quality (-q6), deletes old unwanted files (-d), and executes the commands right away (-x). -Recommendations -~~~~~~~~~~~~~~~ +### Recommendations + Since encoding eats a lot of CPU, you should start it at a low priority. -The simplest way is to run ``nice -n19 brutha`` instead of only ``brutha``. +The simplest way is to run `nice -n19 brutha` instead of only *brutha*. -Symbolic links -~~~~~~~~~~~~~~ -brutha ignores symbolic links by default, but can follow links outside of the -source path, or inside the source path, using options ``--outside`` and ``--inside``. +### Symbolic links -This is modelled after mpd's ``follow_outside_symlinks`` and ``follow_inside_symlinks`` options. +brutha ignores symbolic links by default, but can follow links outside +of the source path, or inside the source path, using options `--outside` +and `--inside`. -Changes -------- +This is modelled after mpd's `follow_outside_symlinks` and +`follow_inside_symlinks` options. -+ 1.1.1 +## Changes ++ 1.1.1 - Fix some corner cases with directory walking. - + 1.1.0 - - Add sox option to guard against clipping. - Add options to create hardlinks or reflinks. - Make parallel the default if available. - Code and documentation improvements. - Support for newer parallel versions. - + 1.0.2 - - Code improvements. - Show defaults in command-line help. - + 1.0.1 - - Bugfixes. +## Future - -Future ------- - -`brutha` is considered feature-complete. +*brutha* is considered feature-complete. If you want to help, here are some possibilities: -* Support other formats (currently only FLAC to Ogg Vorbis, with Ogg Vorbis and MP3 as exact copies). +* Support other formats (currently only FLAC to Ogg Vorbis, with Ogg + Vorbis and MP3 as exact copies). * Make mutagen optional (only required for frequency / bit depth checks). * Support downmixing (5.1 to 2.0 for instance) -Contributions can be sent in the form of git patches, to laurent@bachelier.name. +Contributions can be sent in the form of git patches, to +. diff --git a/setup.py b/setup.py index bc27602..8ba608b 100755 --- a/setup.py +++ b/setup.py @@ -12,7 +12,8 @@ name='brutha', version='1.1.1', description='Sync FLAC music files to Ogg Vorbis (or keep lossy as-is)', - long_description=open('README').read(), + long_description=open('README.md').read(), + long_description_content_type='text/markdown', author='Laurent Bachelier', author_email='laurent@bachelier.name', url='http://git.p.engu.in/laurentb/brutha/',