Git Product home page Git Product logo

intermodal's Introduction

Intermodal

A 40' shipping container for the Internet

crate build book chat

Intermodal is a user-friendly and featureful command-line BitTorrent metainfo utility. The binary is called imdl and runs on Linux, Windows, and macOS.

At the moment, creation, viewing, and verification of .torrent files is supported. See the book for examples and usage information.

For more about the project and its goals, check out this post.

demonstration animation

Table of Contents

Installation

Supported Operating Systems

imdl supports Linux, MacOS, and Windows, and should work on other unix OSes. If it does not, please open an issue!

Packages

Operating System Package Manager Package Command
Various Cargo imdl cargo install imdl
Arch Linux Yay intermodal-binAUR yay -S intermodal-bin
Arch Linux Yay intermodalAUR yay -S intermodal
Arch Linux Manual Installation intermodalAUR wiki
Void Linux XBPS intermodal xbps-install -S intermodal
Windows Scoop intermodal scoop install intermodal

Pre-built binaries

Pre-built binaries for Linux, macOS, and Windows can be found on the releases page.

Linux and MacOS Install Script

You can use the following command on Linux and MacOS to download the latest binary, just replace DEST with the directory where you'd like to install the imdl binary:

curl --proto '=https' --tlsv1.2 -sSf https://imdl.io/install.sh | bash -s -- --to DEST

A good place to install personal binaries is ~/bin, which install.sh uses when --to is not supplied. To create the ~/bin directory and install imdl there, do:

curl --proto '=https' --tlsv1.2 -sSf https://imdl.io/install.sh | bash

Additionally, you'll have to add ~/bin to the PATH environment variable, which the system uses to find executables. How to do this depends on the shell.

For sh, bash, and zsh, it should be done in ~/.profile:

echo 'export PATH=$HOME/bin:$PATH' >> ~/.profile

For fish, it should be done in ~/.config/fish/config.fish:

echo 'set -gx PATH ~/bin $PATH' >> ~/.config/fish/config.fish

Cargo

imdl is written in Rust and can be built from source and installed with cargo install imdl. To get Rust, use the rustup installer.

Shell Completion Scripts

Shell completion scripts for Bash, Zsh, Fish, PowerShell, and Elvish are included in all binary releases.

For Bash, move imdl.bash to $XDG_CONFIG_HOME/bash_completion or /etc/bash_completion.d/.

For Fish, move imdl.fish to $HOME/.config/fish/completions/.

For the Z shell, move _imdl to one of your $fpath directories.

For PowerShell, add . _imdl.ps1 to your PowerShell profile (note the leading period). If the _imdl.ps1 file is not on your PATH, do . /path/to/_imdl.ps1 instead.

The imdl binary can also generate the same completion scripts at runtime, using the completions command:

$ imdl completions --shell bash > imdl.bash

The --dir argument can be used to write a completion script into a directory with a filename that's appropriate for the shell. For example, the following command will write the Z shell completion script to $fpath[0]/_imdl:

$ imdl completions --shell zsh --dir $fpath[0]

Usage

Online documentation is available in the book, hosted here.

Commands

Adding --help to any command will print help text about how to use that command, including detailed information about any command-line arguments it accepts.

So, to get information about imdl torrent create, run imdl torrent create --help.

Additionally, the same help text is available online in the book.

Examples

The intro to the book has a few simple examples. Check the FAQ for more complex usage examples.

FAQ

The FAQ covers a variety of specific use-cases. If there's a use case you think should be covered, feel free to open an issue.

Notes for Packagers

First off, thank you very much! If I can do anything to make packaging Intermodal easier, please don't hesistate to open an issue.

The Intermodal binary is called imdl, and the suggested name for the package is intermodal.

Intermodal is written in Rust, and can be built with cargo build --release.

Intermodal is distributed under the Creative Commons Zero, a public domain dedication with a fallback all-permissive license. The SPDX identifier of the CC0 is CC0-1.0.

Build Artifacts

There are a number of build artifacts: the binary, the man pages, the changelog, and the shell completion scripts.

The binary is built with cargo, and the other artifacts are built gen, located in bin/gen.

The binary can be built with:

cargo build --release

gen requires help2man to be installed, which is used to generate man pages from subcommand --help strings.

The rest of the build artifacts can be built with gen:

cargo run --package gen -- --bin target/release/imdl all

The path to the built imdl executable should be passed to gen with the --bin flag.

After running the above commands, the following table shows the location of the built artifacts.

Artifact Location
Binary target/release/imdl
Man Pages target/gen/man/*
Completion Scripts target/gen/completions/*
Changelog target/gen/CHANGELOG.md
Readme target/gen/README.md

Release Updates

If you'd like to receive an update whenever a new version is released, you can watch the intermodal repository in "Releases only" mode.

Chat

The primary chat is on Discord.

Contributing

Your bug reports, feature requests, pull requests, and design help are much appreciated!

Check out issues with the "good first issue" label for some ideas.

Quite a few files are generated by the program in bin/gen. Some files are generated from templates, so those templates should be edited to make changes to those files:

  • bin/gen/templates/SUMMARY.md -> book/src/SUMMARY.md
  • bin/gen/templates/README.md -> README.md
  • bin/gen/templates/introduction.md -> book/src/introduction.md

Some files are completely generated, and so shouldn't be manually edited at all:

  • CHANGELOG.md
  • book/src/commands/*
  • completions/*
  • man/*

All files can be regenerated by running cargo run --package gen all, or just gen, if you have just installed.

The changelog is generated from YAML metadata in commit messages. Here is an example commit message, with metadata:

Upgrade foo

Upgrade foo to v7.5, which is much better.

type: changed
pr:
- https://github.com/casey/intermodal/pull/1
fixes:
- https://github.com/intermodal/issues/2
- https://github.com/intermodal/issues/3

The only required field is type. To see the possible values for type, run cargo run --package gen commit-types.

Benchmarks

Performance benchmarks can be run with:

$ cargo bench --features bench

The benchmark framework used is criterion.

The bench targets themselves are in the benches directory. These targets call benchmarking functions in src/benches.rs, which are only enabled when the bench feature is enabled.

Semantic Versioning

Intermodal follows semantic versioning.

In particular:

  • v0.0.X: Breaking changes may be introduced at any time.
  • v0.X.Y: Breaking changes may only be introduced with a minor version number bump.
  • vX.Y.Z: Breaking changes may only be introduced with a major version number bump

Unstable Features

To avoid premature stabilization and excessive version churn, unstable features are unavailable unless the --unstable / -u flag is passed, for example imdl --unstable torrent create .. Unstable features may be changed or removed at any time.

Acknowledgments

The formatting of imdl torrent show is entirely copied from torf, an excellent command-line torrent creator, editor, and viewer.

intermodal's People

Contributors

anniecherk avatar atomgardner avatar casey avatar celeo avatar esiegel avatar rare-magma avatar rrybarczyk avatar schnerring avatar strickinato avatar thatnerdypikachu avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

intermodal's Issues

Unicode Normalization

Per this issue: pobrn/mktorrent#14

I don't exactly understand the issue here, or what the right thing to do might be. Being aware of unicode normalization would be a good idea.

Document Prior Art and Alternatives in Readme

I'd like to document alternatives to intermodal, as well as prior art and related applications. Right now this should include other applications and libraries for creating torrents. I should also add notes on when you might want to use something other than intermodal.

Acknowledge that all these apps and libraries were studied for inspiration for intermodal.

Torrent Creating Apps and Libraries

Usenet Uploaders

File inclusion and exclusion

  • Skip .DS_Store and other common junk files
  • Skip files that start with a . or are hidden via attribute
  • Skip symlinks unless --follow-symlinks is passed
  • Support literal path inclusion and exclusion (paths to specific files, path to dir)
  • Support glob inclusion and exclusion
  • Support regex inclusion and exclusion

Bencode Subcommands

Add bencode subcommands for interacting with bencoded data:

  • imdl bencode validate --input PATH validate bencode file(s) at PATH, showing any validation errors encountered
  • imdl bencode convert --format yaml PATH convert bencoded files at path to given format.

Add fancy progress indicator

Should indicate progress for number of files processed, number of bytes (total) processed, and number of bytes (per file) processed.

Draw the file tree incrementally, with progress indicator next to each file.

This should work for torrent creation, and torrent verification.

Started in #213.

Check bencode implementation

Ideally check against other major bencode implementations. It may be good to fuzz it as well.

  • Doesn't panic
  • Everything that produces a value round-trips to the same buffer
  • Check that fails/valids match another implementation

Improve hashing and verification performance

The speed of torrent creation and verification could use some work. I picked SHA1 and MD5 implementations basically at random, and there are lots of potential performance bottlenecks in how I hash and verify pieces.

Also, #440 reports performance problems when linking against musl on Linux. If allocation, I/O, or threading is slow with musl, then general performance improvements might cause less allocation and/or I/O (I don't do any threading) which might lessen the performance impact of linking against musl.

First thing will be to set up repeatable benchmarking, so there's stable baseline to compare against. Next there are a bunch of things that are worth trying.

  • Split crate into binary and library, to make benchmarking possible
  • Set up benchmarking
  • Set up flamegraph generation
  • Tests which exercise incomplete reads and uneven files, and probably some known good infohashes of large files and directories of files. (They can be generated with an algorithm, so they don't need to be saved in the repo.)
  • Test for musl vs libc builds
  • Try jemalloc (There might be an issue with musl and jemalloc.)
  • Consider unifying hashing and verification. Hashing and verification are implemented separately, but with some work they could be unified. This would be a good idea before pursuing performance improvements that will otherwise need to be duplicated.
  • Fix ultra-cringe byte-at-a-time hashing inner loop
  • Experiment with buffering more data from each file
  • Experiment with reading file contents in a background thread
  • Experiment with async I/O
  • Experiment with multiple threads
  • Make new demo gif with faster speeds
  • Consider mmaping files

Add support for automatic piece size selection

Automatic piece size selection should be based on a goal .torrent file size. Consider making this the default when a piece size is not specified on the command line. (However, when creating a magnet link, it might be better not to specify this.)

Add support for WebTorrent

I'm not sure if WebTorrent requires or benefits from extra fields, but if so, they should be supported by imdl torrent create.

Clippy lints

  • Make sure lints are a hard error in github actions workflow.
  • Forbid as conversions
  • Consider forbidding println/eprintln, since we should be printing to the environment.
  • Lint on missing docs

Support HTTP seeds / web seeds

BEP is 0019, and metainfo key is url-list. (Actually there is a second BEP, 0017.)

The rules for trailing slashes and single vs. multi-file torrents are somewhat weird, so a nice additional feature would be to issue HEAD requests against the reconstructed URLs to make sure that the files can actually be retrieved.

Here is the relevant part of the spec:

Metadata Extension

In the main area of the metadata file and not part of the "info" section, will be a new key, "url-list". This key will refer to a one or more URLs, and will contain a list of web addresses where torrent data can be retrieved. This key may be safely ignored if the client is not capable of using it.

For example (on multiple lines for readability):
d 8:announce27:http://tracker.com/announce 8:url-list26:http://mirror.com/file.exe 4:info...
If the "url-list" URL ends in a slash, "/" the client must add the "name" from the torrent to make the full URL. This allows .torrent generators to treat this field same for single file and multi-file torrents.

Multi-File Torrents

BitTorrent clients normally use the "name" from the torrent info section to make a folder, then use the "path/file" items from the info section within that folder. For the case of Multi-File torrents, the "url-list" must be a root folder where a client could add the same "name" and "path/file" to create the URL for the request.

For example:
... 8:url-list22:http://mirror.com/pub/ 4:infod5:filesld6:lengthi949e4:pathl10:Readme.txte e4:name7:michael

A client would use all that to build a url: http://mirror.com/pub/michael/Readme.txt

Consider adding config file

A config file might be useful as a source of defaults for different trackers. It should include a profiles section, which allows setting defaults for different trackers, to be used with imdl torrent create --profile PROFILE

Another useful feature might be configuring file path patterns to ignore.

Create a man page

There should be a single, canonical source of documentation, from which is produced a readme, a man page, and an online book. (Probably blocked on clap-rs/clap#552.)

Shill

Shill 1: The Shillining.

Continuous Integration

Add continuous integration and release building. Consider Travis, Appveyor, and Github Actions, and any I might have missed.

Test on:

  • Linux
  • macOS
  • Windows

Survey other torrent creation apps for useful features

I'd like to make sure that I don't miss any potentially useful features, since most of the features I've encountered are very easy to implement. I should survey other apps and libraries, including those in #1, as well as the various torrent clients that can be used to create torrents.

Publish my GPG keys

I should publish my GPG keys, so that commits and releases can be verified by third parties.

Future Development

Potential future directions:

  • Most likely: A simple and useful single-file format (gzip + tar) plus structured releases with a focus on excellent metadata + web index.html for browser viewing.

  • Usenet: Functionality for simultaneously creating usenet and bittorrent releases. Should allow for torrent to be losslessly translated into a NZB, and vice-versa. The ideal flow is: Publisher creates a release with a normal torrent, and also uploads 512KiB blocks of the torrent to usenet. The blocks should be encrypted with a private key distributed with the torrent. Upon receiving the torrent, the whole torrent or missing blocks can be mechanically retrieved from usenet.

  • Releases: Functionality for naming and formatting releases. One particularly promising avenue is creating a standard for release names that are both machine readable and human readable. Current release names (like Foo.Bar.S01E17.FMT-GRP) are close to being machine readable, but many different standards exist, so parsing them is awkward and complex. If standardizing those names is politically untenable, then maybe standardizing and adding a machine-readable blob, perhaps bech32 tlv, would be more feasible. Beyond that, an actual schema for the contents of torrents would make building rich services (search, auto-download, library manager, streaming, etc) much easier. For the first type of release, I'm considering albums or research papers.

  • S3: Publish a release to an S3 bucket.

  • Web: Generate HTML index files so a release can be published to the web.

  • Plex/Sonarr/Radarr: Think about how intermodal-generated torrents can be compatible these apps. (Most likely by making sure the metadata is in the right place.)

Add color to output

Print error in red, message in bold. Add always/auto/never --use-color flag.

Write a readme

In particular, make sure people get a good sense that imdl has expansive future goals, but right now is very usable to create torrents.

Check for non-portable file names

Check for filenames that might cause problems on different systems and throw an error, unless a flag is passed. I'm not sure how strict to be. Some ideas for checks, some which are clearly too strict:

  • Only allow ascii: Since non-ascii encoding may be buggy
  • Don't allow spaces: For shell-safe paths
  • Don't allow siblings whose names differ only by case: For case sensitive file systems)
  • Only allow /a-zA-Z0-9_.-/: maximum crazy
  • Don't allow leading -: conflicts with options and flags
  • Dont' allow \/:*?"<>|: I think for windows

Figure out what The Internet Archive uses to create torrents

In order to learn what features might be useful, I'm interested in finding torrent creation apps currently in use. The Internet Archive creates a lot of torrents, but I'm not sure what they they use.

I'm particularly interested in their use of esoteric and recent BEPs. Jason Scott might be able to help.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.