Today I Learned

ins8s

686 posts by harsha @ins8s

Enable 4k UHD video streaming in Firefox

y default, Firefox does not support the VP9 WebM codec sites like YouTube use to deliver 4k quality video. If you visit a video that supports 4k you won’t even see the option available under the Quality menu.

Test video: https://www.youtube.com/watch?v=Bey4XXJAqS8

To enable it:

  1. visit about:config
  2. search for webm
  3. double click media.mediasource.webm.enabled

demo

And now refresh YouTube result

doriankarter June 21, 2018

Share Audio from MacOS with two Bluetooth Devices

Connect both headphones via bluetooth. Both should say connected on the Bluetooth setting page.

  1. In Finder menu hit Go -> Utilities -> Audio Midi Setup

  2. You should see both your headphones listed on the left here.

  3. Hit the “+” button at the bottom left and select “Create Multi-Output Device” (You may rename the device if you wish)

  4. Select your bose headphones from the list on the right to add to the Multi-Output Device.

  5. Right-click on the Multi-Output Device you just created and use device for sound output and play alerts and sound through this device.

  6. You may also select which device as your master device to sync across all your connected headphones.

  7. I also selected Drift Correction for slave devices - I’m not 100% sure what this does but I think it makes sure that your devices stay in sync to the audio/video playing on your computer.

  8. Watch away. Note that you won’t be able to adjust ouput volume from Macbook any more, instead volume is adjusted individually at each headphone, which is pretty neat.

Every possible combination of given letters - BASH

If you want to create every possible word or combination of letters (or any other characters) you can use very simple BASH function:

$ echo {a..c}

This command will print all possible letters starting with a and ending on c (inclusive), so the result is:

a b c

You can get every possible combination of letters from the given range, which length is larger than 1, i.e.:

$ echo {a..c}{a..c}

This command will print every possible combination of letters starting with a and ending on c (inclusive) with another letter from the same range. The result result is:

aa ab ac ba bb bc ca cb cc

Print memory usage in Python program

The psutil library is great for this, but you’ll probably have to install it with pip. Then it’s as simple as:

import psutil
print(psutil.virtual_memory())

It will print out a named tuple with total physical memory, available memory, percent, used, free etc like this:

svmem(total=25769803776L, available=8386338816L, percent=67.5, used=22414565376L, free=72933376L, active=8504508416L, inactive=8313405440L, wired=5596651520L)

psutil has a lot of other great functionality too. You can see connected users, look at process information, spawn new processes, look at network connections and much more. It’s worth checking out.

Download Audio from YouTube

-i - ignore errors

-c - continue

-t - use video title as file name

--extract-audio - extract audio track

--audio-format mp3 - convert to mp3

--audio-quality 0 - the best audio quality

--yes-playlist - affirm that url points to a playlist

YT_URL - video url from youtube

# Download single entry
youtube-dl -i --extract-audio --audio-format mp3 --audio-quality 0 YT_URL

# Download playlist
youtube-dl -ict --yes-playlist --extract-audio --audio-format mp3 --audio-quality 0 https://www.youtube.com/playlist?list=UUCvVpbYRgYjMN7mG7qQN0Pg

# Download playlist, --download-archive downloaded.txt add successfully downloaded files into downloaded.txt
youtube-dl --download-archive downloaded.txt --no-overwrites -ict --yes-playlist --extract-audio --audio-format mp3 --audio-quality 0 --socket-timeout 5 https://www.youtube.com/playlist?list=UUCvVpbYRgYjMN7mG7qQN0Pg

# Retry until success, no -i option
while ! youtube-dl --download-archive downloaded.txt --no-overwrites -ct --yes-playlist --extract-audio --audio-format mp3 --audio-quality 0 --socket-timeout 5 <YT_PlayList_URL>; do echo DISCONNECTED; sleep 5; done```

Creating SSH Shared Keys for Cluster Users

Set up SSH shared keys for all of the compute nodes. To create a public and private key, do the following:

  1. Run the following on the head node:

    > ssh-keygen -t rsa
  2. Accept default settings and do not submit a passphrase (press Enter 3 times).

  3. From the head node, SSH onto each and every node in the cluster by hostname (including the head node) to append the host’s public key to the .ssh/known_hosts file.

    > for i in node01 node02 node03; do ssh -o StrictHostKeyChecking=no ${i} hostname; done
  4. Append the contents of id_rsa.pub to the authorized_keys file.

    > cat .ssh/id_rsa.pub >> .ssh/authorized_keys
  5. Create the .ssh directory on all compute nodes in case it does not exist.

    > for i in node04 node05 node06; do ssh ${i} mkdir .ssh; done
  6. Copy the .ssh folder to the nodes.

    > for i in node01 node02 node03; do scp -r .ssh/id_rsa.pub ${i}:~/.ssh; done
  7. (Optional) To allow users access the compute nodes from the head node, copy the authorized keys to the nodes.

    > for i in node01 node02 node03; do scp -r .ssh/authorized_keys ${i}:~/.ssh; done

Remove unused Docker containers and images

1) Before deleting all the containers, force stop them:

docker ps -q -a | xargs docker stop

2) Then delete the containers using:

docker ps -q -a | xargs docker rm

3) Now delete all the dangling images using:

docker rmi $(docker images | grep “^<none>” | awk ‘{print $3}’)

One-liner

docker kill $(docker ps -q) && docker rm $(docker ps -a -q) && docker rmi $(docker images -q)

Remove .DS_Store files from Mac OS X

.DS_Store files are automatically created by Mac OS X Finder in browsed directories. These files contain information about system configuration. If you upload them along with other files, the files can be misused to obtain information about your computer. For more information, see Apple security updates

Remove all DS_Store files

  1. Select Applications > Utilities to launch Terminal.

  2. Run the following UNIX command:

    sudo find / -name ".DS_Store" -depth -exec rm {} \;

  3. When prompted for a password enter your Mac OS X Administrator password.

Automatically remove DS_Store files periodically.

  1. Select Applications > Utilities to launch Terminal.

  2. Run the following UNIX command: sudo crontab -e

  3. In the vi editor, press the letter I on your keyboard once and enter the following command:

    15 1 * * * root find / -name ".DS_Store" -depth -exec rm {} \;

    This crontab entry has the following format:

    <Minute> <Hour> <DayOfMonth> <Month> <DayOfWeek> <User Command>

    The system automatically runs the command at 1:15 AM everyday. To configure the command for a different time, use different values.

  4. To save the entry, press the Esc key once, then simultaneously press Shift+Z+Z.

Access The Latest Lifecycle Methods In An Old App

With the release of React 16.3 we have access to some new lifecycle methods and are in the first phase of what will eventually result in the deprecation and removal of componentWillMount, componentWillReceiveProps, and componentWillUpdate.

You may not be ready to move your project to React 16.3, but that doesn’t mean you can’t start migrating your lifecycle methods now. We’ll need a polyfill — react-lifecycles-compat.

import React from 'react';
import { pollyfill } from 'react-lifecycles-compat';

class MyComponent extends React.Component {
  static getDerivedStateFromProps(nextProps, prevState) {
    // ...
  }

  render() { ... }
}
polyfill(MyComponent)

export default MyComponent;

For any of our class components for which we’d like to start using the new lifecycle methods, we just need to import the polyfill function and then transform the class component with the polyfill before exporting it.

source

Reach Into An Object For Nested Data With Get

Among the many lodash utilities is _.get for getting data from nested objects. You can specify where to reach into the nested data of an object using a path.

Consider the following awkwardly nested object:

const resp = {
  error: {
    errors: [
      { message: "Something went wrong" },
    ],
  },
};

Here is how we might reach into this with vanilla JavaScript:

resp.error.errors[0].message;

Reaching into this for the message value is tricky because as soon as the resp object contains differently nested data, an error is likely to be thrown. We can simultaneously avoid a bunch of exception handling logic and provide a default value with the _.get function:

_.get(resp, 'error.errors[0].message', 'Default error message');

If we decide to not include a default value, then undefined will be used.

Mock A Function With Return Values Using Jest

Jest provides a collection of utilities for working with mocked functions. To create a mock function, do:

jest.fn()

// assign it to a variable
const fakeFunc = jest.fn();

// pass it as a prop
<SpecialInput handleChange={jest.fn()} />

A mocked function can then be attributed with a return value.

const fakeFunc = jest.fn();
fakeFunc.mockReturnValue("hello");
fakeFunc(); // => "hello"

The mockReturnValue() function ensures that the value is returned whenever your function is called.

We can also limit the return value to occurring just once.

const fakeFunc = jest.fn();
fakeFunc.mockReturnValueOnce("hello");
fakeFunc(); // => "hello"
fakeFunc(); // => null

mockReturnValueOnce() ensures the value is returned once and all subsequent calls yield null.

Set A Window To Its Default Zoom Level

Often when showing my screen to someone else or connecting to a project, I have to adjust the zoom level of my current window by hitting Cmd + a bunch of times. Once I am done I usually do some guess work to get the screen size back to what I am used to, hitting Cmd - a couple times.

There is an easier way.

Hitting Cmd 0 will return the window back to its default zoom level.

h/t Jake Worth

Debug Jest Tests In create-react-app

When you put a debugger; statement in one of your Jest tests and run yarn test, the test runner will ignore the debug statement and run to completion. This is because Jest defaults to parallelizing tests which won’t mix well with manual debugging intervention.

If we want to be able to run our Jest tests through a debugger. We will need two things. First, we need a debugging environment — Chrome’s devtools will work well for this. Second, we need our tests to run in band. The react-scripts documentation recommends adding a second, debug-specific test command to your package.json:

"scripts": {
  "test:debug": "react-scripts --inspect-brk test --runInBand --env=jsdom"
}

You can now run yarn test:debug which will start a paused debug session. Open chrome at chrome://inspect to access and open the debugging session panel. Now, debug away.

Configuring The Pager

When you run Git commands that produce a bunch of output, Git will use a pager to present the content starting at the beginning, rather than spitting it all out to the screen at once. This will almost always come in handy for commands like git-diff and git-log.

By default, Git uses less as its pager.

You can also choose to configure it to something else by updating your git config file or by running the following command:

$ git config --global core.pager 'more'

If you’d like to turn the pager off altogether, set it to a blank string.

$ git config --global core.pager ''

source

Building A React App In The Browser

There are a couple relatively new tools that give you just about everything you need to build a React app in the browser.

The first is CodeSandbox. It has a couple pre-configured environments for different technologies. The main one is React. CodeSandbox describes itself as such:

an online editor that helps you create web applications, from prototype to deployment.

The second, which just released out of beta, is Glitch which comes with projects like react-starter so that you can jump into a React project that is ready to roll. Glitch describes itself as:

the friendly community where you’ll build the app of your dreams

You can quickly build and publish React apps in either of these and share them with the world.

Test Coverage Stats With Jest

Jest is a delightful tool for JavaScript testing from Facebook. As your project evolves and you add tests (or perhaps choose to not add tests) you may wonder what kind of test coverage you have. What is the overall coverage? Which files are well covered and which are seriously lacking?

Use the --coverage flag to get this information.

$ jest --coverage

After running all of your tests a table will be output to the terminal with a list of files and their respective coverage percentages in terms of statement, branch, function, and line coverage.

---------------------------|----------|----------|----------|----------|----------------|
File                       |  % Stmts | % Branch |  % Funcs |  % Lines |Uncovered Lines |
---------------------------|----------|----------|----------|----------|----------------|

This can help guide you to what parts of your app may need more testing.

Test Files In create-react-app

Any .js files placed in the __tests__ directory will be treated as tests by Jest when running yarn test. If you don’t want to place all of your files in that directory and especially if you want to co-located your test files with the source files, you can name them with the .test.js or .spec.js suffixes.

Any files in your create-react-app project ending in these suffixes will be treated by Jest as test files and included in test runs.

There are more details in the docs.

Enforce Specific Values With PropTypes

Being able to constrain our user interfaces to very specific values is valuable. This makes our interfaces easier to reason about and easier to test. PropTypes in general are one of the ways that we constrain our UIs. We can go even further than simple type constraints by limiting a prop to a specific set of values, an enum if you will.

MyComponent.propTypes = {
  flavor: PropTypes.oneOf(['Vanilla', 'Chocolate', 'Strawberry']),
};

The docs say about oneOf():

You can ensure that your prop is limited to specific values by treating it as an enum.

If we use MyComponent with a value such as Pistachio, we’ll have a console warning to answer for.

source

Create Listing Of All Middleman Pages

Middleman is a handy tool for quickly throwing together a bunch of static pages with layout and templating help at the ready. Once you have a handful of pages up and running, you’ll probably want a way to quickly navigate to them. You can add a quick listing of all the pages with a couple helpers provided by Middleman.

<ul>
  <% sitemap.resources.each do |resource| %>
    <li><%= link_to(resource.path, resource.path) %></li>
  <% end %>
</ul>

The sitemap.resources variable will contain a list of all the resources that get processed and served by the Middleman app. The link_to helper makes it easy to turn those into links.

Because resources includes images and other assets, you may want to filter down to just html files which could look something like the following:

<ul>
  <% sitemap.resources
       .select { |resource| resource.path =~ /html$/ }
       .each do |resource|
  %>
    <li><%= link_to(resource.path, resource.path) %></li>
  <% end %>
</ul>

Just add the snippet to whatever page you’d like the page listing to appear on.

Add React With Webpacker To A New Rails App

Webpacker makes it easy to manage app-like JavaScript in the context of a Rails app. React is a great candidate for this kind of webpack-powered JavaScript processing pipeline.

To set up a new Rails project with Webpack and React wired up, add the --webpack=react flag:

$ rails new rails-react-app --webpack=react

As part of the generated app, you will get a app/javascript/packs directory with a hello_react.jsx file that has a really basic React component.

source

Seeding And Generating Random Integers

It is easy enough to generate a series of random numbers using the Random module’s int function.

Random.int(10);

This will generate a random integer between 0 and 9.

You may notice that the randomness is the same each time you run your program. That is because you have fixed seed. To make sure you have a different seed each time your program runs, you can initialize the random number generator with something different at each run, such as the current time.

Random.init(int_of_float(Js.Date.now()));

See a live example here.

Scoping Variables With A Block Statement

A solid way to keep code readable and easy to understand is to ditch the terse one-liners in favor of breaking things up across multiple lines and using self-documenting variable names. This isn’t all good though. Each new variable that is defined is a handle on some data that can be misused later in the syntax scope.

JavaScript has a nice way of being clear about the scope of certain variables:

let parsedDate;
{
  let [month, day, year] = input.split('-');
  parsedDate = new Date(year, month, day);
}

// do something with parsedDate

The month, day, and year variables are scoped to the { ... } which is a block statement. This helps communicate and enforce that those variables are only to be used in that very specific context. Other developers and our future selves won’t be able to erroneously use those variables.

Of course, breaking out a function is another way of accomplishing this. Sequestering code in a different part of the file is not always the best answer though. Sometimes you want it locally fenced off. For those times, use a block statement.

Apply Styles To The Last Child Of A Specific Type

The :last-child pseudo-class is a way of specifying styling that will only be applied to an element if it is the last child among its siblings. What if we have elements that are declared amongst elements of another type? This can complicate that styling.

The styling

span:last-child {
  color: red;
}

won’t take effect on our last span here

<div>
  <span>One</span>
  <span>Two</span>
  <span>Three</span>
  <div>Something unrelated</div>
</div>

because amongst its siblings it isn’t the last.

One way of getting around this is with the :last-of-type pseudo-class.

span:last-of-type {
  color: red;
}

See a live example here.

Show The Good And The Bad With Git Bisect

The git bisect command is a powerful tool for tracking down a past commit where something verifiable about the code changed — whether it be visual or functional. After using git bisect to traverse back and forth through your commit history, you may be wondering where things stand.

The git bisect log command will show you each commit that has been inspected and whether you’ve marked it as good or bad.

These records can be handy for double checking your work if you’re worried that you made a mistake along the way.

String Interpolation With Quoted Strings

Stapling strings together with the ++ operator can be tedious and clunky. If you have string variables that you’d like to interpolate, you can piece them together much more easily using quoted strings.

We can get close to a solution with the standard quoted string syntax.

let greeting = (greetee) => {
  {|Hello, $(greetee)!|}
};

Js.log(greeting("World")); // => "Hello, $(greetee)!"

This isn’t quite right though. We have to take advantage of a preprocessing hook provided by Bucklescript. The j hook supports unicode and allows variable interpolation.

let greeting = (greetee) => {
  {j|Hello, $(greetee)!|j}
};

Js.log(greeting("World")); // => "Hello, World!"

To use this pre-processor we have to include j in the quoted string like so {j|...|j}.

See a live example here.

Get The Location And Size Of An Element

All modern browsers ship with the getBoundingClientRrect() function. It can be invoked for any DOM element. It returns the x and y coordinates of the element within the browser viewport as well as the height and width values and the top and bottom values along the y-axis and left and right values along the x-axis.

> $0.getBoundingClientRect()
{
  "x": 381.421875,
  "y": 70,
  "width": 1030.578125,
  "height": 48,
  "top": 70,
  "right": 1412,
  "bottom": 118,
  "left": 381.421875
}

For instance, this is the result of invoking it against a header element on the MDN page linked above.

A Component Is Just A Bag Of Data

If you write enough React using JSX, it is easy to forget that you’re not working with markup. Everything — divs, h1s, 3rd party components, your components — all get boiled down to JavaScript objects full of data.

Any given React component is really just a bag of data. Try doing a console.log to see. Here is an example from an earlier post.

const ParentWithClick = ({ children }) => {
  return (
    <React.Fragment>
      {React.Children.map(children || null, (child, i) => {
        console.log(child);
        return <child.type {...child.props} key={i} onClick={handleClick} />;
      })}
    </React.Fragment>
  );
};

const App = () => (
  <div>
    <ParentWithClick>
      <span>Click this span</span>
    </ParentWithClick>
  </div>
);

Looking in the console, we see the following output:

Object {type: "span", key: null, ref: null, props: Object, _owner: Object…}
 type: "span"
 key: null
 ref: null
 props: Object
  children: "Click this span"
 _owner: Object
 _store: Object

It contains information about the component itself and because of the tree structure of this data, you could potentially expand the props —> children sections several times for certain components.

See a live example here.

Spread The Rest With ES6

The spread operator provided by ES6 is a powerful syntactic feature. One way it can be used is to capture the rest of an object or array in a variable.

const pokemon = ["Charmander", "Squirtle", "Bulbasaur"];
const [first, ...rest] = pokemon;

console.log("Remaining: ", rest); // Remaining: ["Squirtle", "Bulbasaur"]

const gymLeaders = {
  brock: "rock",
  misty: "water",
  surge: "electric",
  erika: "grass"
};
let { brock, erika, ...otherLeaders } = gymLeaders;

console.log(otherLeaders); // Object {misty: "water", surge: "electric"}

Using this spread destructuring we can capture the remaining parts of an array or object in a variable. We can also use this syntax in a function signature to grab specific items from an incoming object argument without losing track of the rest — this is especially useful in React.js development when dealing with incoming props.

This is a stage 4 feature and may not be available in your particular environment.

See a live example here.

Mapping Over One Or Many Children

In Dynamically Add Props To A Child Component, I talked about how a child element can be reconstituted with additional props. The approach I showed will only work in the case of a single child being nested in that component. What if you want your component to account for one, many, or even children?

React comes with a built-in function for mapping that handles these cases.

const ParentWithClick = ({ children }) => {
  return (
    <React.Fragment>
      {React.Children.map(children || null, (child, i) => {
        return <child.type {...child.props} key={i} onClick={handleClick} />;
      })}
    </React.Fragment>
  );
};

The React.Children.map function allows mapping over one or many elements and if children is null or undefined, it will return null or undefined respectively.

See a live example here.

Dynamically Add Props To A Child Component

If your component has an element nested in it, then it will receive a children prop. There are a number of things you can do beyond simply including the children as part of the rendered output of the component. One thing you can do is put additional props on the child.

const ParentWithClick = ({ children }) => {
  return (
    <children.type
      {...children.props}
      onClick={() => alert("You clicked me!")}
    />
  );
};

This ParentWithClick component will reconstitute its child component with its given props and a new onClick prop.

Here is how it can be used:

const App = () => {
  return (
    <ParentWithClick>
      <span>Hello!</span>
    </ParentWithClick>
  );
};

Click on Hello! and you’ll see the alert.

Minor caveat: multiple children and a string child will need to be handled differently.

See a live example here.

Who Is Your Favorite Child?

When we put some content inside the open and close tags of one of our components, we get access to it as the children prop.

const Parent = ({children}) => {
  return (
    <React.Fragment>
      <p>These are my favorites:</p>
      {children}
    </React.Fragment>
  );
}

const App = () => (
  <div>
    <Parent>
      Greg and Marsha
    </Parent>
  </div>
);

What happens if we also provide an explicit children prop to Parent?

const App = () => (
  <div>
    <Parent children={"Jan and Peter"}>
      Greg and Marsha
    </Parent>
  </div>
);

Which will take precedence when we destructure children in the parent component?

In the example above, we’ll still see Greg and Marsha rendered. The content placed inside the tags will take precedence over the explicit children prop.

See a live example here.

Custom Type Checking Error Messages With Yup

In Yup Schemas Are Validated Asynchronously, I showed how to create a simple schema that allows you to enforce that a value is a number.

const numSchema = yup.number();

If we use this schema to validate something that isn’t a number, Yup will provide a lengthy default message. Here is what we get if we validate against 'hey':

this must be a number type, but the final value was: NaN (cast from the value "hey").

This value isn’t necessarily suitable for displaying to a user. We can customize the type checking error message by redefining our schema with the typeError() function:

const numSchema = yup.number().typeError("Invalid number");