diff --git a/CHANGES.md b/CHANGES.md index 805eb06..12125f4 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -2,6 +2,13 @@ Update history for **tochd**. +## v.0.9 - July 06, 2022 + +- changed: now flushes the output of job message without buffering, useful for + live monitoring and reading stdout the moment it is written +- new: added a "PKGBUILD" for use with `pacman`, can be used to generate an + Archlinux package + ## v0.8 - March 30, 2022 - new: pseudo compiled bundle of the script with pyinstaller to build a diff --git a/PKGBUILD b/PKGBUILD new file mode 100644 index 0000000..e781148 --- /dev/null +++ b/PKGBUILD @@ -0,0 +1,24 @@ +# Maintainer: Tuncay +pkgname=tochd +pkgver=0.9 +pkgrel=1 +pkgdesc="Convert game ISO and archives to CD CHD for emulation." +arch=('any') +url="https://github.com/thingsiplay/tochd" +license=('MIT') +depends=('python3' 'p7zip' 'mame-tools') +source=("$pkgname-$pkgver.tar.gz::https://github.com/thingsiplay/$pkgname/archive/refs/tags/v$pkgver.tar.gz") +noextract=('Makefile' 'install.sh' 'uninstall.sh') + +sha256sums=('3ea72f97182c6696c52503814cc16c61f33027b4534bc2d1bed39d688e57163c') + +check() { + cd "$pkgname-$pkgver" + python3 "$pkgname.py" --version +} + +package() { + cd "$pkgname-$pkgver" + mkdir -p "$pkgdir/usr/local/bin" + install -m 755 -T "$pkgname.py" "$pkgdir/usr/local/bin/${pkgname%%.*}" +} diff --git a/README.md b/README.md index 65b3973..3bbc4b0 100644 --- a/README.md +++ b/README.md @@ -49,6 +49,18 @@ If you have an older Python version, then you might want to check the binary [release](https://github.com/thingsiplay/tochd/releases) package, which bundles up the script and Python interpreter to create a standalone executable. +### Optional: Install on Archlinux using PKGBUILD package + +If you are using an Archlinux based system, then you can instead build an +Archlinux package and install with `pacman`. Use `makepkg` to generate a .zst +package or download from the +[https://github.com/thingsiplay/tochd/releases](releases) page. +Then use `sudo pacman -U tochd-x.x-x-any.pkg.tar.zst` command (where the `x` +should be replaced by the version number of generated package) to install into +the system. To remove the package, just use `sudo pacman -R tochd`. The +installation directory is under "/usr/local/bin" and differs from the +"install.sh" that is provided with the repository. + ### Optional: Makefile and PyInstaller (you can ignore this part) The included "Makefile" is to build the package with the standalone binary. It @@ -167,12 +179,13 @@ threads with option `-t` (short for `--threads`). # Additional notes, workarounds and quirks -If you forcefully terminate the script while working, then unfinished files and -especially temporary folders cannot be removed anymore. These files and folders -can take up huge amount of space! Temporary folders are hidden starting with a -dot "." in the name, followed by the name of archive and some random characters -added. Make sure these files are deleted, in case you forcefully terminate the -script. +If you forcefully terminate the entire script while working, then unfinished +files and especially temporary folders cannot be removed anymore. These files +and folders can take up huge amount of space! Temporary folders are hidden +starting with a dot "." in the name, followed by the name of archive and some +random characters. Make sure these files are deleted. The regular `Ctrl+c` to +abort current job is *not* a forced termination of script (unless option `-E` +is in effect). Some archives contain multiple folders, each with ISO files of same name. These are usually intended to copy and overwrite files in a main folder as a meaning @@ -180,3 +193,19 @@ of patching. However, the script has no understanding and knowledge about this and would try to convert each .iso file on it's own. As a workaround all .iso files in the archive are ignored when a sheet type such as CUE or GDI files are found. + +Somtimes .cue or .iso files found in an archive have a different name than the +archive filename itself. Sometimes one of them lack important informations and +you need to determine which of them is "correct". In example translations could +have important information encoded in the filename of the .cue, which would be +lost, as the .CHD file is automatically renamed to match the .zip or .7z +archive in example. Use in such situations option `-R` (short for +`--no-rename`) to prevent that and leave the original files name found inside +the archive. + +There are cases where the audio files can be a different format than what the +.cue (or .gdi) files expect. In example there are cases where the audio files +are in .ape format and need to be converted to .wav first. If you are unsure +about this, then look into any provided readme file or the .cue sheet itself. +Then convert them before handing it over to .chd conversion. + diff --git a/tochd.py b/tochd.py index c289d50..03b28a9 100644 --- a/tochd.py +++ b/tochd.py @@ -24,7 +24,7 @@ class App: """ Contains all settings and meta information for the application. """ name: str = 'tochd' - version: str = '0.8' + version: str = '0.9' types = { 'sheet': ('gdi', 'cue',), 'image': ('iso',), @@ -315,7 +315,8 @@ def message_job(self, message: str, path: Path, jobindex: int) -> None: pad_size: int = 12 pad_size = pad_size - len(str(jobindex)) padded_msg = message.rjust(pad_size) - print('Job', jobindex, padded_msg + ':\t', path.as_posix()) + message = f"Job {jobindex} {padded_msg}:\t{path.as_posix()}" + print(message, flush=True) return None @classmethod @@ -438,11 +439,12 @@ def parse_arguments(args: list[str] | None = None) -> Argparse: 'file', default=[], nargs='*', - help=('input multiple files or folders with ISOs or archives, all ' - 'supported files from a given folder are processed, in addition ' - 'use option dash "-" to read files from stdin for each line, ' - 'note: option "--" stops parsing for options and everything ' - 'after is a filename even those starting with a single dash "-"') + help=('input multiple files or folders containing ISOs or archive ' + 'files, script will search for supported files in top level of ' + 'a folder, a single dash "-" character will instruct the script ' + 'to read file paths from stdin for each line, note: option ' + 'double dash "--" will stop parsing for program options and ' + 'everything following that is interpreted as a file') ) parser.add_argument( @@ -478,14 +480,14 @@ def parse_arguments(args: list[str] | None = None) -> Argparse: dest='p7z', metavar='CMD', default='7z', - help='change path or command name of 7z program' + help='change path or command name to 7z program' ) parser.add_argument( '--chdman', metavar='CMD', default='chdman', - help='change path or command name of chdman program' + help='change path or command name to chdman program' ) parser.add_argument( @@ -494,7 +496,7 @@ def parse_arguments(args: list[str] | None = None) -> Argparse: default=None, help=('destination path to an existing directory to save the CHD file ' 'under, the temporary subfolder will be created here too, ' - 'defaults to each input files original directory') + 'defaults to each input files original folder') ) parser.add_argument( @@ -503,7 +505,8 @@ def parse_arguments(args: list[str] | None = None) -> Argparse: action='store_true', help=('disable automatic renaming for CHD files that were build from ' 'archives, no test for "if file already exists" can be provided ' - 'beforehand, only applicable to archive sources') + 'beforehand, only applicable to archive sources, without this ' + 'option files from archives are renamed to match the archive') ) parser.add_argument( @@ -534,8 +537,9 @@ def parse_arguments(args: list[str] | None = None) -> Argparse: type=int, choices=range(0, cpucount()), help=('limit the number of processor cores to utilize during ' - 'creation of the CHD files with "chdman", 0 will not limit ' - f'the cores (available: {os.cpu_count()}), defaults to "0"') + 'creation of the CHD files with "chdman" for each thread, ' + f'0 will not limit the cores (available: {os.cpu_count()}), ' + 'defaults to "0"') ) parser.add_argument( @@ -559,9 +563,9 @@ def parse_arguments(args: list[str] | None = None) -> Argparse: default=False, action='store_true', help=('Ctrl+c (SIGINT) will stop execution of script immadiately ' - 'with exit code 255, without this option the script defaults to ' - 'canceling current job process properly and continue with next ' - 'job process') + 'with exit code 255, which could leave temporary files, without ' + 'this option the script defaults to canceling current job ' + 'process properly and continue with next job process in list') ) parser.add_argument(