Portfolio

Open source projects

yanki — github.com/danielparks/yanki

Yanki is a Python command line tool made to simplify creating thousands of video flashcards from YouTube videos.

I initially wrote Yanki to be just an authoring tool to produce flashcards for the popular Anki app, but it turned out that my classmates had trouble using the app. To make it useful to them, I updated Yanki to produce static HTML that can be hosted on any web server (demo).

Internally, Yanki includes a simple parser for deck definition files, and uses ffmpeg to trim, crop, and/or slow video. Since ffmpeg is primarily single threaded when encoding media, Yanki uses Python’s asyncio to run multiple instance in parallel and significantly cut down the time needed to process thousands of flashcards.

git-status-vars — github.com/danielparks/git-status-vars

better-timeout ↑1 ~/projects/git-status-vars 8:58:24 PM eval $(time git-status-vars) 0.02s elapsed 80% CPU better-timeout ↑1 ~/projects/git-status-vars 8:58:31 PM 0.1s echo $head_ref1_short ↑$head_ahead unstaged: $unstaged_count better-timeout ↑1 unstaged: 3

I configure my shell prompt to display information about the current git repository, e.g. the name of the curent branch, whether or not there are uncommitted changes, etc. Loading that information required multiple calls to git which added a noticeable delay after every command, including trivial ones like cd. Git-status-vars uses libgit2 to quickly read common repo information, then prints the information in shell variable form. The output can be evaled and the variables can be used in a prompt.

htmlize — github.com/danielparks/htmlize

Htmlize is a Rust crate that correctly encodes and decodes HTML text.

assert!(htmlize::escape_attribute("1 & 2 < 3") == "1 &amp; 2 &lt; 3"); assert!(htmlize::unescape("3 &times 4 &gt; 10") == "3 × 4 > 10");

Encoding entities is easy and fast, but decoding entities correctly has two major edge cases: not all entities have to end with a semicolon, e.g. &copy (©), and some entities contain other entities as a prefix, e.g. &copysr; (℗).

After significant experimentation, I chose two fast decode algorithms. They produce identical results, but switching between them trades faster compile times (with a perfect hash) for faster run times (with a massive match tree generated by my crate matchgen).

matchgen — github.com/danielparks/matchgen

In Rust, the fastest way to match the next substring from a limited set of strings is to use a tree of match statements. Matchgen makes that easy.

matchgen::TreeMatcher::new("pub fn decode", "u8") .doc("Decode basic HTML entities.") .add(b"&amp;", "b'&'") .add(b"&lt;", "b'<'") .add(b"&gt;", "b'>'") .add(b"&quot;", "b'\"'") .write_to_out_dir("decoder.rs")?;

puppet-golang — github.com/danielparks/puppet-golang

Simple yet flexible Go installations with Puppet.

class { 'golang': ensure => latest, }

armature — github.com/danielparks/armature

Armature is a tool for deploying Puppet environments and modules. It sets up Puppet environments for each branch in your control repo and installs modules as specified by the Puppetfile for each environment.

❯ armature deploy-branches my-puppet-code.git '*'

Armature is designed to replace r10k for certain, very specific use cases. It does not have nearly as many features, but it is much faster.